@splitsoftware/splitio-commons 1.6.2-rc.8 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +4 -1
- package/cjs/evaluator/index.js +5 -5
- package/cjs/listeners/browser.js +9 -11
- package/cjs/sdkClient/client.js +19 -7
- package/cjs/sdkFactory/index.js +7 -25
- package/cjs/services/splitApi.js +4 -4
- package/cjs/storages/AbstractSplitsCacheAsync.js +1 -1
- package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
- package/cjs/storages/KeyBuilderSS.js +9 -9
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -1
- package/cjs/storages/inLocalStorage/index.js +15 -11
- package/cjs/storages/inMemory/InMemoryStorage.js +11 -8
- package/cjs/storages/inMemory/InMemoryStorageCS.js +11 -8
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +65 -37
- package/cjs/storages/inMemory/{uniqueKeysCacheInMemory.js → UniqueKeysCacheInMemory.js} +24 -25
- package/cjs/storages/inMemory/{uniqueKeysCacheInMemoryCS.js → UniqueKeysCacheInMemoryCS.js} +10 -12
- package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +37 -2
- package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +100 -0
- package/cjs/storages/inRedis/{uniqueKeysCacheInRedis.js → UniqueKeysCacheInRedis.js} +16 -4
- package/cjs/storages/inRedis/index.js +6 -4
- package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +81 -0
- package/cjs/storages/pluggable/ImpressionsCachePluggable.js +2 -19
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +126 -0
- package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +61 -0
- package/cjs/storages/pluggable/inMemoryWrapper.js +8 -6
- package/cjs/storages/pluggable/index.js +51 -18
- package/cjs/storages/utils.js +73 -0
- package/cjs/sync/submitters/submitterManager.js +1 -1
- package/cjs/sync/submitters/telemetrySubmitter.js +4 -37
- package/cjs/sync/submitters/uniqueKeysSubmitter.js +4 -3
- package/cjs/trackers/impressionObserver/utils.js +1 -17
- package/cjs/trackers/uniqueKeysTracker.js +1 -1
- package/cjs/utils/lang/maps.js +15 -7
- package/cjs/utils/redis/RedisMock.js +31 -0
- package/cjs/utils/settingsValidation/index.js +7 -4
- package/esm/evaluator/index.js +5 -5
- package/esm/listeners/browser.js +9 -11
- package/esm/sdkClient/client.js +19 -7
- package/esm/sdkFactory/index.js +7 -25
- package/esm/services/splitApi.js +4 -4
- package/esm/storages/AbstractSplitsCacheAsync.js +1 -1
- package/esm/storages/AbstractSplitsCacheSync.js +1 -1
- package/esm/storages/KeyBuilderSS.js +8 -8
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -1
- package/esm/storages/inLocalStorage/index.js +16 -12
- package/esm/storages/inMemory/InMemoryStorage.js +13 -10
- package/esm/storages/inMemory/InMemoryStorageCS.js +12 -9
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +64 -37
- package/esm/storages/inMemory/{uniqueKeysCacheInMemory.js → UniqueKeysCacheInMemory.js} +22 -24
- package/esm/storages/inMemory/{uniqueKeysCacheInMemoryCS.js → UniqueKeysCacheInMemoryCS.js} +10 -12
- package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +37 -2
- package/esm/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +100 -0
- package/esm/storages/inRedis/{uniqueKeysCacheInRedis.js → UniqueKeysCacheInRedis.js} +15 -3
- package/esm/storages/inRedis/index.js +5 -3
- package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +78 -0
- package/esm/storages/pluggable/ImpressionsCachePluggable.js +2 -19
- package/esm/storages/pluggable/TelemetryCachePluggable.js +126 -0
- package/esm/storages/pluggable/UniqueKeysCachePluggable.js +58 -0
- package/esm/storages/pluggable/inMemoryWrapper.js +8 -6
- package/esm/storages/pluggable/index.js +52 -19
- package/esm/storages/utils.js +65 -0
- package/esm/sync/submitters/submitterManager.js +1 -1
- package/esm/sync/submitters/telemetrySubmitter.js +4 -36
- package/esm/sync/submitters/uniqueKeysSubmitter.js +4 -3
- package/esm/trackers/impressionObserver/utils.js +1 -15
- package/esm/trackers/uniqueKeysTracker.js +1 -1
- package/esm/utils/lang/maps.js +15 -7
- package/esm/utils/redis/RedisMock.js +28 -0
- package/esm/utils/settingsValidation/index.js +7 -4
- package/package.json +2 -2
- package/src/consent/sdkUserConsent.ts +1 -1
- package/src/evaluator/index.ts +6 -6
- package/src/listeners/browser.ts +9 -13
- package/src/logger/.DS_Store +0 -0
- package/src/sdkClient/client.ts +21 -8
- package/src/sdkClient/sdkClient.ts +1 -1
- package/src/sdkFactory/index.ts +10 -33
- package/src/sdkFactory/types.ts +2 -2
- package/src/services/splitApi.ts +6 -6
- package/src/services/types.ts +2 -2
- package/src/storages/AbstractSplitsCacheAsync.ts +1 -1
- package/src/storages/AbstractSplitsCacheSync.ts +1 -1
- package/src/storages/KeyBuilderSS.ts +13 -11
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +0 -1
- package/src/storages/inLocalStorage/index.ts +17 -12
- package/src/storages/inMemory/AttributesCacheInMemory.ts +7 -7
- package/src/storages/inMemory/ImpressionCountsCacheInMemory.ts +2 -2
- package/src/storages/inMemory/InMemoryStorage.ts +14 -10
- package/src/storages/inMemory/InMemoryStorageCS.ts +13 -10
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +72 -35
- package/src/storages/inMemory/{uniqueKeysCacheInMemory.ts → UniqueKeysCacheInMemory.ts} +26 -28
- package/src/storages/inMemory/{uniqueKeysCacheInMemoryCS.ts → UniqueKeysCacheInMemoryCS.ts} +15 -17
- package/src/storages/inRedis/EventsCacheInRedis.ts +1 -1
- package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +51 -8
- package/src/storages/inRedis/ImpressionsCacheInRedis.ts +2 -22
- package/src/storages/inRedis/TelemetryCacheInRedis.ts +122 -1
- package/src/storages/inRedis/{uniqueKeysCacheInRedis.ts → UniqueKeysCacheInRedis.ts} +25 -12
- package/src/storages/inRedis/index.ts +6 -3
- package/src/storages/pluggable/ImpressionCountsCachePluggable.ts +92 -0
- package/src/storages/pluggable/ImpressionsCachePluggable.ts +3 -23
- package/src/storages/pluggable/TelemetryCachePluggable.ts +147 -1
- package/src/storages/pluggable/UniqueKeysCachePluggable.ts +67 -0
- package/src/storages/pluggable/inMemoryWrapper.ts +6 -6
- package/src/storages/pluggable/index.ts +56 -20
- package/src/storages/types.ts +53 -70
- package/src/storages/utils.ts +78 -0
- package/src/sync/submitters/submitter.ts +2 -2
- package/src/sync/submitters/submitterManager.ts +1 -1
- package/src/sync/submitters/telemetrySubmitter.ts +9 -39
- package/src/sync/submitters/types.ts +33 -17
- package/src/sync/submitters/uniqueKeysSubmitter.ts +6 -5
- package/src/trackers/impressionObserver/utils.ts +1 -16
- package/src/trackers/impressionsTracker.ts +2 -2
- package/src/trackers/strategy/strategyDebug.ts +4 -4
- package/src/trackers/strategy/strategyNone.ts +9 -9
- package/src/trackers/strategy/strategyOptimized.ts +9 -9
- package/src/trackers/uniqueKeysTracker.ts +6 -6
- package/src/types.ts +0 -2
- package/src/utils/lang/maps.ts +20 -8
- package/src/utils/redis/RedisMock.ts +33 -0
- package/src/utils/settingsValidation/index.ts +5 -5
- package/types/services/types.d.ts +2 -2
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
- package/types/storages/KeyBuilderSS.d.ts +5 -2
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +0 -1
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +23 -9
- package/types/storages/inMemory/uniqueKeysCacheInMemory.d.ts +9 -9
- package/types/storages/inMemory/uniqueKeysCacheInMemoryCS.d.ts +2 -4
- package/types/storages/inRedis/EventsCacheInRedis.d.ts +1 -1
- package/types/storages/inRedis/ImpressionCountsCacheInRedis.d.ts +3 -1
- package/types/storages/inRedis/ImpressionsCacheInRedis.d.ts +0 -1
- package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +16 -1
- package/types/storages/inRedis/uniqueKeysCacheInRedis.d.ts +8 -2
- package/types/storages/pluggable/ImpressionCountsCachePluggable.d.ts +16 -0
- package/types/storages/pluggable/ImpressionsCachePluggable.d.ts +1 -2
- package/types/storages/pluggable/TelemetryCachePluggable.d.ts +17 -1
- package/types/storages/pluggable/UniqueKeysCachePluggable.d.ts +20 -0
- package/types/storages/types.d.ts +42 -49
- package/types/storages/utils.d.ts +8 -0
- package/types/sync/submitters/submitter.d.ts +2 -2
- package/types/sync/submitters/telemetrySubmitter.d.ts +2 -10
- package/types/sync/submitters/types.d.ts +27 -18
- package/types/trackers/impressionObserver/utils.d.ts +0 -8
- package/types/trackers/strategy/strategyNone.d.ts +2 -2
- package/types/trackers/strategy/strategyOptimized.d.ts +2 -2
- package/types/trackers/uniqueKeysTracker.d.ts +1 -1
- package/types/types.d.ts +0 -2
- package/types/utils/lang/maps.d.ts +6 -2
- package/types/utils/redis/RedisMock.d.ts +4 -0
- package/types/utils/settingsValidation/index.d.ts +0 -1
- package/cjs/storages/metadataBuilder.js +0 -12
- package/esm/storages/metadataBuilder.js +0 -8
- package/src/storages/metadataBuilder.ts +0 -11
- package/types/sdkClient/types.d.ts +0 -18
- package/types/storages/inMemory/CountsCacheInMemory.d.ts +0 -20
- package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +0 -20
- package/types/storages/inRedis/CountsCacheInRedis.d.ts +0 -9
- package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +0 -9
- package/types/sync/offline/LocalhostFromFile.d.ts +0 -2
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +0 -2
- package/types/sync/submitters/eventsSyncTask.d.ts +0 -8
- package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +0 -5
- package/types/sync/submitters/impressionCountsSyncTask.d.ts +0 -13
- package/types/sync/submitters/impressionsSyncTask.d.ts +0 -14
- package/types/sync/submitters/metricsSyncTask.d.ts +0 -12
- package/types/sync/submitters/submitterSyncTask.d.ts +0 -10
- package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +0 -5
- package/types/sync/syncTaskComposite.d.ts +0 -5
- package/types/trackers/filter/bloomFilter.d.ts +0 -10
- package/types/trackers/filter/dictionaryFilter.d.ts +0 -8
- package/types/trackers/filter/types.d.ts +0 -5
- package/types/utils/timeTracker/index.d.ts +0 -70
|
@@ -34,8 +34,6 @@ exports.base = {
|
|
|
34
34
|
telemetryRefreshRate: 3600,
|
|
35
35
|
// publish evaluations each 300 sec (default value for OPTIMIZED impressions mode)
|
|
36
36
|
impressionsRefreshRate: 300,
|
|
37
|
-
// publish unique Keys each 900 sec (15 min)
|
|
38
|
-
uniqueKeysRefreshRate: 900,
|
|
39
37
|
// fetch offline changes each 15 sec
|
|
40
38
|
offlineRefreshRate: 15,
|
|
41
39
|
// publish events every 60 seconds after the first flush
|
|
@@ -114,7 +112,6 @@ function settingsValidation(config, validationParams) {
|
|
|
114
112
|
scheduler.segmentsRefreshRate = fromSecondsToMillis(scheduler.segmentsRefreshRate);
|
|
115
113
|
scheduler.offlineRefreshRate = fromSecondsToMillis(scheduler.offlineRefreshRate);
|
|
116
114
|
scheduler.eventsPushRate = fromSecondsToMillis(scheduler.eventsPushRate);
|
|
117
|
-
scheduler.uniqueKeysRefreshRate = fromSecondsToMillis(scheduler.uniqueKeysRefreshRate);
|
|
118
115
|
scheduler.telemetryRefreshRate = fromSecondsToMillis(validateMinValue('telemetryRefreshRate', scheduler.telemetryRefreshRate, 60));
|
|
119
116
|
// Default impressionsRefreshRate for DEBUG mode is 60 secs
|
|
120
117
|
if ((0, lang_1.get)(config, 'scheduler.impressionsRefreshRate') === undefined && withDefaults.sync.impressionsMode === constants_1.DEBUG)
|
|
@@ -135,8 +132,8 @@ function settingsValidation(config, validationParams) {
|
|
|
135
132
|
if (storage)
|
|
136
133
|
withDefaults.storage = storage(withDefaults);
|
|
137
134
|
// Validate key and TT (for client-side)
|
|
135
|
+
var maybeKey = withDefaults.core.key;
|
|
138
136
|
if (validationParams.acceptKey) {
|
|
139
|
-
var maybeKey = withDefaults.core.key;
|
|
140
137
|
// Although `key` is required in client-side, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
|
|
141
138
|
if (withDefaults.mode === constants_1.LOCALHOST_MODE && maybeKey === undefined) {
|
|
142
139
|
withDefaults.core.key = 'localhost_key';
|
|
@@ -154,6 +151,12 @@ function settingsValidation(config, validationParams) {
|
|
|
154
151
|
}
|
|
155
152
|
}
|
|
156
153
|
}
|
|
154
|
+
else {
|
|
155
|
+
// On server-side, key is undefined and used to distinguish from client-side
|
|
156
|
+
if (maybeKey !== undefined)
|
|
157
|
+
log.warn('Provided `key` is ignored in server-side SDK.'); // @ts-ignore
|
|
158
|
+
withDefaults.core.key = undefined;
|
|
159
|
+
}
|
|
157
160
|
// Current ip/hostname information
|
|
158
161
|
// @ts-ignore, modify readonly prop
|
|
159
162
|
withDefaults.runtime = runtime(withDefaults);
|
package/esm/evaluator/index.js
CHANGED
|
@@ -15,21 +15,21 @@ function treatmentsException(splitNames) {
|
|
|
15
15
|
return evaluations;
|
|
16
16
|
}
|
|
17
17
|
export function evaluateFeature(log, key, splitName, attributes, storage) {
|
|
18
|
-
var
|
|
18
|
+
var parsedSplit;
|
|
19
19
|
try {
|
|
20
|
-
|
|
20
|
+
parsedSplit = storage.splits.getSplit(splitName);
|
|
21
21
|
}
|
|
22
22
|
catch (e) {
|
|
23
23
|
// Exception on sync `getSplit` storage. Not possible ATM with InMemory and InLocal storages.
|
|
24
24
|
return treatmentException;
|
|
25
25
|
}
|
|
26
|
-
if (thenable(
|
|
27
|
-
return
|
|
26
|
+
if (thenable(parsedSplit)) {
|
|
27
|
+
return parsedSplit.then(function (split) { return getEvaluation(log, split, key, attributes, storage); }).catch(
|
|
28
28
|
// Exception on async `getSplit` storage. For example, when the storage is redis or
|
|
29
29
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
30
30
|
function () { return treatmentException; });
|
|
31
31
|
}
|
|
32
|
-
return getEvaluation(log,
|
|
32
|
+
return getEvaluation(log, parsedSplit, key, attributes, storage);
|
|
33
33
|
}
|
|
34
34
|
export function evaluateFeatures(log, key, splitNames, attributes, storage) {
|
|
35
35
|
var parsedSplits;
|
package/esm/listeners/browser.js
CHANGED
|
@@ -4,7 +4,6 @@ import { OPTIMIZED, DEBUG, NONE } from '../utils/constants';
|
|
|
4
4
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
5
5
|
import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
|
|
6
6
|
import { isConsentGranted } from '../consent';
|
|
7
|
-
import { telemetryCacheStatsAdapter } from '../sync/submitters/telemetrySubmitter';
|
|
8
7
|
var VISIBILITYCHANGE_EVENT = 'visibilitychange';
|
|
9
8
|
var PAGEHIDE_EVENT = 'pagehide';
|
|
10
9
|
var UNLOAD_EVENT = 'unload';
|
|
@@ -68,25 +67,25 @@ var BrowserSignalListener = /** @class */ (function () {
|
|
|
68
67
|
BrowserSignalListener.prototype.flushData = function () {
|
|
69
68
|
if (!this.syncManager)
|
|
70
69
|
return; // In consumer mode there is not sync manager and data to flush
|
|
70
|
+
var _a = this.settings.urls, events = _a.events, telemetry = _a.telemetry;
|
|
71
71
|
// Flush impressions & events data if there is user consent
|
|
72
72
|
if (isConsentGranted(this.settings)) {
|
|
73
|
-
var eventsUrl = this.settings.urls.events;
|
|
74
73
|
var sim = this.settings.sync.impressionsMode;
|
|
75
74
|
var extraMetadata = {
|
|
76
75
|
// sim stands for Sync/Split Impressions Mode
|
|
77
76
|
sim: sim === OPTIMIZED ? OPTIMIZED : sim === DEBUG ? DEBUG : NONE
|
|
78
77
|
};
|
|
79
|
-
this._flushData(
|
|
80
|
-
this._flushData(
|
|
78
|
+
this._flushData(events + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
|
|
79
|
+
this._flushData(events + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
|
|
81
80
|
if (this.storage.impressionCounts)
|
|
82
|
-
this._flushData(
|
|
81
|
+
this._flushData(events + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, fromImpressionCountsCollector);
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
if (this.storage.uniqueKeys)
|
|
84
|
+
this._flushData(telemetry + '/v1/keys/cs/beacon', this.storage.uniqueKeys, this.serviceApi.postUniqueKeysBulkCs);
|
|
83
85
|
}
|
|
84
86
|
// Flush telemetry data
|
|
85
|
-
if (this.storage.telemetry)
|
|
86
|
-
|
|
87
|
-
var telemetryCacheAdapter = telemetryCacheStatsAdapter(this.storage.telemetry, this.storage.splits, this.storage.segments);
|
|
88
|
-
this._flushData(telemetryUrl + '/v1/metrics/usage/beacon', telemetryCacheAdapter, this.serviceApi.postMetricsUsage);
|
|
89
|
-
}
|
|
87
|
+
if (this.storage.telemetry)
|
|
88
|
+
this._flushData(telemetry + '/v1/metrics/usage/beacon', this.storage.telemetry, this.serviceApi.postMetricsUsage);
|
|
90
89
|
};
|
|
91
90
|
BrowserSignalListener.prototype.flushDataIfHidden = function () {
|
|
92
91
|
// Precondition: document defined
|
|
@@ -100,7 +99,6 @@ var BrowserSignalListener = /** @class */ (function () {
|
|
|
100
99
|
if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
|
|
101
100
|
postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible exception
|
|
102
101
|
}
|
|
103
|
-
cache.clear();
|
|
104
102
|
}
|
|
105
103
|
};
|
|
106
104
|
/**
|
package/esm/sdkClient/client.js
CHANGED
|
@@ -6,6 +6,15 @@ import { validateTrafficTypeExistance } from '../utils/inputValidation/trafficTy
|
|
|
6
6
|
import { SDK_NOT_READY } from '../utils/labels';
|
|
7
7
|
import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TRACK } from '../utils/constants';
|
|
8
8
|
import { IMPRESSION, IMPRESSION_QUEUEING } from '../logger/constants';
|
|
9
|
+
import { isStorageSync } from '../trackers/impressionObserver/utils';
|
|
10
|
+
var treatmentNotReady = { treatment: CONTROL, label: SDK_NOT_READY };
|
|
11
|
+
function treatmentsNotReady(splitNames) {
|
|
12
|
+
var evaluations = {};
|
|
13
|
+
splitNames.forEach(function (splitName) {
|
|
14
|
+
evaluations[splitName] = treatmentNotReady;
|
|
15
|
+
});
|
|
16
|
+
return evaluations;
|
|
17
|
+
}
|
|
9
18
|
/**
|
|
10
19
|
* Creator of base client with getTreatments and track methods.
|
|
11
20
|
*/
|
|
@@ -22,7 +31,11 @@ export function clientFactory(params) {
|
|
|
22
31
|
stopTelemetryTracker(queue[0] && queue[0].label);
|
|
23
32
|
return treatment;
|
|
24
33
|
};
|
|
25
|
-
var evaluation =
|
|
34
|
+
var evaluation = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
|
|
35
|
+
evaluateFeature(log, key, splitName, attributes, storage) :
|
|
36
|
+
isStorageSync(settings) ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
37
|
+
treatmentNotReady :
|
|
38
|
+
Promise.resolve(treatmentNotReady); // Promisify if async
|
|
26
39
|
return thenable(evaluation) ? evaluation.then(function (res) { return wrapUp(res); }) : wrapUp(evaluation);
|
|
27
40
|
}
|
|
28
41
|
function getTreatmentWithConfig(key, splitName, attributes) {
|
|
@@ -41,7 +54,11 @@ export function clientFactory(params) {
|
|
|
41
54
|
stopTelemetryTracker(queue[0] && queue[0].label);
|
|
42
55
|
return treatments;
|
|
43
56
|
};
|
|
44
|
-
var evaluations =
|
|
57
|
+
var evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
|
|
58
|
+
evaluateFeatures(log, key, splitNames, attributes, storage) :
|
|
59
|
+
isStorageSync(settings) ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
60
|
+
treatmentsNotReady(splitNames) :
|
|
61
|
+
Promise.resolve(treatmentsNotReady(splitNames)); // Promisify if async
|
|
45
62
|
return thenable(evaluations) ? evaluations.then(function (res) { return wrapUp(res); }) : wrapUp(evaluations);
|
|
46
63
|
}
|
|
47
64
|
function getTreatmentsWithConfig(key, splitNames, attributes) {
|
|
@@ -49,13 +66,8 @@ export function clientFactory(params) {
|
|
|
49
66
|
}
|
|
50
67
|
// Internal function
|
|
51
68
|
function processEvaluation(evaluation, splitName, key, attributes, withConfig, invokingMethodName, queue) {
|
|
52
|
-
var isSdkReady = readinessManager.isReady() || readinessManager.isReadyFromCache();
|
|
53
69
|
var matchingKey = getMatching(key);
|
|
54
70
|
var bucketingKey = getBucketing(key);
|
|
55
|
-
// If the SDK was not ready, treatment may be incorrect due to having Splits but not segments data.
|
|
56
|
-
if (!isSdkReady) {
|
|
57
|
-
evaluation = { treatment: CONTROL, label: SDK_NOT_READY };
|
|
58
|
-
}
|
|
59
71
|
var treatment = evaluation.treatment, label = evaluation.label, changeNumber = evaluation.changeNumber, _a = evaluation.config, config = _a === void 0 ? null : _a;
|
|
60
72
|
log.info(IMPRESSION, [splitName, matchingKey, treatment, label]);
|
|
61
73
|
if (validateSplitExistance(log, readinessManager, splitName, label, invokingMethodName)) {
|
package/esm/sdkFactory/index.js
CHANGED
|
@@ -2,12 +2,9 @@ import { sdkReadinessManagerFactory } from '../readiness/sdkReadinessManager';
|
|
|
2
2
|
import { impressionsTrackerFactory } from '../trackers/impressionsTracker';
|
|
3
3
|
import { eventTrackerFactory } from '../trackers/eventTracker';
|
|
4
4
|
import { telemetryTrackerFactory } from '../trackers/telemetryTracker';
|
|
5
|
-
import { getMatching } from '../utils/key';
|
|
6
|
-
import { shouldBeOptimized } from '../trackers/impressionObserver/utils';
|
|
7
5
|
import { validateAndTrackApiKey } from '../utils/inputValidation/apiKey';
|
|
8
6
|
import { createLoggerAPI } from '../logger/sdkLogger';
|
|
9
7
|
import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
|
|
10
|
-
import { metadataBuilder } from '../storages/metadataBuilder';
|
|
11
8
|
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
12
9
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
13
10
|
import { strategyDebugFactory } from '../trackers/strategy/strategyDebug';
|
|
@@ -20,44 +17,29 @@ import { NONE, OPTIMIZED } from '../utils/constants';
|
|
|
20
17
|
*/
|
|
21
18
|
export function sdkFactory(params) {
|
|
22
19
|
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, impressionsObserverFactory = params.impressionsObserverFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, filterAdapterFactory = params.filterAdapterFactory;
|
|
23
|
-
var log = settings.log;
|
|
20
|
+
var log = settings.log, impressionsMode = settings.sync.impressionsMode;
|
|
24
21
|
// @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid API Key, etc.
|
|
25
22
|
// On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
|
|
26
23
|
// We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
|
|
27
24
|
validateAndTrackApiKey(log, settings.core.authorizationKey);
|
|
28
25
|
var sdkReadinessManager = sdkReadinessManagerFactory(log, platform.EventEmitter, settings.startup.readyTimeout);
|
|
29
26
|
var readiness = sdkReadinessManager.readinessManager;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
impressionsQueueSize: settings.scheduler.impressionsQueueSize,
|
|
33
|
-
eventsQueueSize: settings.scheduler.eventsQueueSize,
|
|
34
|
-
uniqueKeysCacheSize: settings.scheduler.uniqueKeysCacheSize,
|
|
35
|
-
optimize: shouldBeOptimized(settings),
|
|
36
|
-
// ATM, only used by InLocalStorage
|
|
37
|
-
matchingKey: getMatching(settings.core.key),
|
|
38
|
-
splitFiltersValidation: settings.sync.__splitFiltersValidation,
|
|
39
|
-
// ATM, only used by PluggableStorage
|
|
40
|
-
mode: settings.mode,
|
|
41
|
-
impressionsMode: settings.sync.impressionsMode,
|
|
42
|
-
// Callback used to emit SDK_READY in consumer mode, where `syncManagerFactory` is undefined,
|
|
43
|
-
// or partial consumer mode, where it only has submitters, and therefore it doesn't emit readiness events.
|
|
27
|
+
var storage = storageFactory({
|
|
28
|
+
settings: settings,
|
|
44
29
|
onReadyCb: function (error) {
|
|
45
30
|
if (error)
|
|
46
31
|
return; // Don't emit SDK_READY if storage failed to connect. Error message is logged by wrapperAdapter
|
|
47
32
|
readiness.splits.emit(SDK_SPLITS_ARRIVED);
|
|
48
33
|
readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
49
34
|
},
|
|
50
|
-
|
|
51
|
-
log: log
|
|
52
|
-
};
|
|
53
|
-
var storage = storageFactory(storageFactoryParams);
|
|
35
|
+
});
|
|
54
36
|
// @TODO add support for dataloader: `if (params.dataLoader) params.dataLoader(storage);`
|
|
55
37
|
var telemetryTracker = telemetryTrackerFactory(storage.telemetry, platform.now);
|
|
56
38
|
var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
|
|
57
39
|
var observer = impressionsObserverFactory();
|
|
58
|
-
var uniqueKeysTracker =
|
|
40
|
+
var uniqueKeysTracker = impressionsMode === NONE ? uniqueKeysTrackerFactory(log, storage.uniqueKeys, filterAdapterFactory && filterAdapterFactory()) : undefined;
|
|
59
41
|
var strategy;
|
|
60
|
-
switch (
|
|
42
|
+
switch (impressionsMode) {
|
|
61
43
|
case OPTIMIZED:
|
|
62
44
|
strategy = strategyOptimizedFactory(observer, storage.impressionCounts);
|
|
63
45
|
break;
|
|
@@ -92,7 +74,7 @@ export function sdkFactory(params) {
|
|
|
92
74
|
return managerInstance;
|
|
93
75
|
},
|
|
94
76
|
// Logger wrapper API
|
|
95
|
-
Logger: createLoggerAPI(
|
|
77
|
+
Logger: createLoggerAPI(log),
|
|
96
78
|
settings: settings,
|
|
97
79
|
}, extraProps && extraProps(ctx));
|
|
98
80
|
}
|
package/esm/services/splitApi.js
CHANGED
|
@@ -107,13 +107,13 @@ export function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
107
107
|
var url = urls.telemetry + "/v1/keys/ss";
|
|
108
108
|
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY));
|
|
109
109
|
},
|
|
110
|
-
postMetricsConfig: function (body) {
|
|
110
|
+
postMetricsConfig: function (body, headers) {
|
|
111
111
|
var url = urls.telemetry + "/v1/metrics/config";
|
|
112
|
-
return splitHttpClient(url, { method: 'POST', body: body }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
112
|
+
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
113
113
|
},
|
|
114
|
-
postMetricsUsage: function (body) {
|
|
114
|
+
postMetricsUsage: function (body, headers) {
|
|
115
115
|
var url = urls.telemetry + "/v1/metrics/usage";
|
|
116
|
-
return splitHttpClient(url, { method: 'POST', body: body }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
116
|
+
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
119
|
}
|
|
@@ -25,7 +25,7 @@ var AbstractSplitsCacheAsync = /** @class */ (function () {
|
|
|
25
25
|
* @param {string} name
|
|
26
26
|
* @param {string} defaultTreatment
|
|
27
27
|
* @param {number} changeNumber
|
|
28
|
-
* @returns {Promise} a promise that is resolved once the split kill operation is performed. The fulfillment value is a boolean: `true` if the
|
|
28
|
+
* @returns {Promise} 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,
|
|
29
29
|
* 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.
|
|
30
30
|
* The promise will never be rejected.
|
|
31
31
|
*/
|
|
@@ -40,7 +40,7 @@ var AbstractSplitsCacheSync = /** @class */ (function () {
|
|
|
40
40
|
* @param {string} name
|
|
41
41
|
* @param {string} defaultTreatment
|
|
42
42
|
* @param {number} changeNumber
|
|
43
|
-
* @returns {
|
|
43
|
+
* @returns {boolean} `true` if the operation successed updating the split, or `false` if no split is updated,
|
|
44
44
|
* 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.
|
|
45
45
|
*/
|
|
46
46
|
AbstractSplitsCacheSync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __extends } from "tslib";
|
|
2
2
|
import { KeyBuilder } from './KeyBuilder';
|
|
3
|
-
var
|
|
3
|
+
export var METHOD_NAMES = {
|
|
4
4
|
t: 'treatment',
|
|
5
5
|
ts: 'treatments',
|
|
6
6
|
tc: 'treatmentWithConfig',
|
|
@@ -11,7 +11,10 @@ var KeyBuilderSS = /** @class */ (function (_super) {
|
|
|
11
11
|
__extends(KeyBuilderSS, _super);
|
|
12
12
|
function KeyBuilderSS(prefix, metadata) {
|
|
13
13
|
var _this = _super.call(this, prefix) || this;
|
|
14
|
-
_this.
|
|
14
|
+
_this.latencyPrefix = _this.prefix + ".telemetry.latencies";
|
|
15
|
+
_this.exceptionPrefix = _this.prefix + ".telemetry.exceptions";
|
|
16
|
+
_this.initPrefix = _this.prefix + ".telemetry.init";
|
|
17
|
+
_this.versionablePrefix = metadata.s + "/" + metadata.n + "/" + metadata.i;
|
|
15
18
|
return _this;
|
|
16
19
|
}
|
|
17
20
|
KeyBuilderSS.prototype.buildRegisteredSegmentsKey = function () {
|
|
@@ -34,16 +37,13 @@ var KeyBuilderSS = /** @class */ (function (_super) {
|
|
|
34
37
|
};
|
|
35
38
|
/* Telemetry keys */
|
|
36
39
|
KeyBuilderSS.prototype.buildLatencyKey = function (method, bucket) {
|
|
37
|
-
return this.
|
|
40
|
+
return this.latencyPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method] + "/" + bucket;
|
|
38
41
|
};
|
|
39
42
|
KeyBuilderSS.prototype.buildExceptionKey = function (method) {
|
|
40
|
-
return this.
|
|
43
|
+
return this.exceptionPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method];
|
|
41
44
|
};
|
|
42
45
|
KeyBuilderSS.prototype.buildInitKey = function () {
|
|
43
|
-
return this.
|
|
44
|
-
};
|
|
45
|
-
KeyBuilderSS.prototype.buildVersionablePrefix = function () {
|
|
46
|
-
return this.metadata.s + "/" + this.metadata.n + "/" + this.metadata.i;
|
|
46
|
+
return this.initPrefix + "::" + this.versionablePrefix;
|
|
47
47
|
};
|
|
48
48
|
return KeyBuilderSS;
|
|
49
49
|
}(KeyBuilder));
|
|
@@ -200,7 +200,6 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
200
200
|
};
|
|
201
201
|
/**
|
|
202
202
|
* Clean Splits cache if its `lastUpdated` timestamp is older than the given `expirationTimestamp`,
|
|
203
|
-
* Clean operation (clear) also updates `lastUpdated` timestamp with current time.
|
|
204
203
|
*
|
|
205
204
|
* @param {number | undefined} expirationTimestamp if the value is not a number, data will not be cleaned
|
|
206
205
|
*/
|
|
@@ -11,9 +11,10 @@ import { SplitsCacheInMemory } from '../inMemory/SplitsCacheInMemory';
|
|
|
11
11
|
import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
|
|
12
12
|
import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
|
|
13
13
|
import { LOG_PREFIX } from './constants';
|
|
14
|
-
import {
|
|
14
|
+
import { DEBUG, NONE, STORAGE_LOCALSTORAGE } from '../../utils/constants';
|
|
15
15
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
|
|
16
|
-
import { UniqueKeysCacheInMemoryCS } from '../inMemory/
|
|
16
|
+
import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
|
|
17
|
+
import { getMatching } from '../../utils/key';
|
|
17
18
|
/**
|
|
18
19
|
* InLocal storage factory for standalone client-side SplitFactory
|
|
19
20
|
*/
|
|
@@ -23,20 +24,23 @@ export function InLocalStorage(options) {
|
|
|
23
24
|
function InLocalStorageCSFactory(params) {
|
|
24
25
|
// Fallback to InMemoryStorage if LocalStorage API is not available
|
|
25
26
|
if (!isLocalStorageAvailable()) {
|
|
26
|
-
params.log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
|
|
27
|
+
params.settings.log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
|
|
27
28
|
return InMemoryStorageCSFactory(params);
|
|
28
29
|
}
|
|
29
|
-
var
|
|
30
|
-
var
|
|
30
|
+
var settings = params.settings, _a = params.settings, log = _a.log, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, _c = _a.sync, impressionsMode = _c.impressionsMode, __splitFiltersValidation = _c.__splitFiltersValidation;
|
|
31
|
+
var matchingKey = getMatching(settings.core.key);
|
|
32
|
+
var keys = new KeyBuilderCS(prefix, matchingKey);
|
|
31
33
|
var expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
|
|
34
|
+
var splits = new SplitsCacheInLocal(log, keys, expirationTimestamp, __splitFiltersValidation);
|
|
35
|
+
var segments = new MySegmentsCacheInLocal(log, keys);
|
|
32
36
|
return {
|
|
33
|
-
splits:
|
|
34
|
-
segments:
|
|
35
|
-
impressions: new ImpressionsCacheInMemory(
|
|
36
|
-
impressionCounts:
|
|
37
|
-
events: new EventsCacheInMemory(
|
|
38
|
-
telemetry:
|
|
39
|
-
uniqueKeys:
|
|
37
|
+
splits: splits,
|
|
38
|
+
segments: segments,
|
|
39
|
+
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
40
|
+
impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
|
|
41
|
+
events: new EventsCacheInMemory(eventsQueueSize),
|
|
42
|
+
telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
|
|
43
|
+
uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
|
|
40
44
|
destroy: function () {
|
|
41
45
|
var _a;
|
|
42
46
|
this.splits = new SplitsCacheInMemory();
|
|
@@ -3,23 +3,26 @@ import { SegmentsCacheInMemory } from './SegmentsCacheInMemory';
|
|
|
3
3
|
import { ImpressionsCacheInMemory } from './ImpressionsCacheInMemory';
|
|
4
4
|
import { EventsCacheInMemory } from './EventsCacheInMemory';
|
|
5
5
|
import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
6
|
-
import { DEBUG,
|
|
7
|
-
import { TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
8
|
-
import { UniqueKeysCacheInMemory } from './
|
|
6
|
+
import { DEBUG, NONE, STORAGE_MEMORY } from '../../utils/constants';
|
|
7
|
+
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
8
|
+
import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
|
|
9
9
|
/**
|
|
10
10
|
* InMemory storage factory for standalone server-side SplitFactory
|
|
11
11
|
*
|
|
12
12
|
* @param params parameters required by EventsCacheSync
|
|
13
13
|
*/
|
|
14
14
|
export function InMemoryStorageFactory(params) {
|
|
15
|
+
var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
|
|
16
|
+
var splits = new SplitsCacheInMemory();
|
|
17
|
+
var segments = new SegmentsCacheInMemory();
|
|
15
18
|
return {
|
|
16
|
-
splits:
|
|
17
|
-
segments:
|
|
18
|
-
impressions: new ImpressionsCacheInMemory(
|
|
19
|
-
impressionCounts:
|
|
20
|
-
events: new EventsCacheInMemory(
|
|
21
|
-
telemetry: params
|
|
22
|
-
uniqueKeys:
|
|
19
|
+
splits: splits,
|
|
20
|
+
segments: segments,
|
|
21
|
+
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
22
|
+
impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
|
|
23
|
+
events: new EventsCacheInMemory(eventsQueueSize),
|
|
24
|
+
telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
|
|
25
|
+
uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemory() : undefined,
|
|
23
26
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
24
27
|
destroy: function () {
|
|
25
28
|
var _a;
|
|
@@ -3,23 +3,26 @@ import { MySegmentsCacheInMemory } from './MySegmentsCacheInMemory';
|
|
|
3
3
|
import { ImpressionsCacheInMemory } from './ImpressionsCacheInMemory';
|
|
4
4
|
import { EventsCacheInMemory } from './EventsCacheInMemory';
|
|
5
5
|
import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
|
|
6
|
-
import { DEBUG,
|
|
6
|
+
import { DEBUG, NONE, STORAGE_MEMORY } from '../../utils/constants';
|
|
7
7
|
import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
|
|
8
|
-
import { UniqueKeysCacheInMemoryCS } from './
|
|
8
|
+
import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
|
|
9
9
|
/**
|
|
10
10
|
* InMemory storage factory for standalone client-side SplitFactory
|
|
11
11
|
*
|
|
12
12
|
* @param params parameters required by EventsCacheSync
|
|
13
13
|
*/
|
|
14
14
|
export function InMemoryStorageCSFactory(params) {
|
|
15
|
+
var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
|
|
16
|
+
var splits = new SplitsCacheInMemory();
|
|
17
|
+
var segments = new MySegmentsCacheInMemory();
|
|
15
18
|
return {
|
|
16
|
-
splits:
|
|
17
|
-
segments:
|
|
18
|
-
impressions: new ImpressionsCacheInMemory(
|
|
19
|
-
impressionCounts:
|
|
20
|
-
events: new EventsCacheInMemory(
|
|
21
|
-
telemetry:
|
|
22
|
-
uniqueKeys:
|
|
19
|
+
splits: splits,
|
|
20
|
+
segments: segments,
|
|
21
|
+
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
22
|
+
impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
|
|
23
|
+
events: new EventsCacheInMemory(eventsQueueSize),
|
|
24
|
+
telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
|
|
25
|
+
uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
|
|
23
26
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
24
27
|
destroy: function () {
|
|
25
28
|
var _a;
|