@splitsoftware/splitio-commons 2.1.0-rc.0 → 2.1.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGES.txt +11 -0
  2. package/LICENSE +1 -1
  3. package/cjs/evaluator/index.js +2 -0
  4. package/cjs/evaluator/matchers/large_segment.js +0 -6
  5. package/cjs/evaluator/matchers/segment.js +0 -6
  6. package/cjs/listeners/browser.js +4 -6
  7. package/cjs/readiness/readinessManager.js +6 -0
  8. package/cjs/sdkClient/client.js +14 -11
  9. package/cjs/sdkClient/sdkClient.js +1 -1
  10. package/cjs/sdkFactory/index.js +9 -14
  11. package/cjs/sdkManager/index.js +2 -1
  12. package/cjs/storages/inLocalStorage/index.js +4 -3
  13. package/cjs/storages/inLocalStorage/validateCache.js +1 -2
  14. package/cjs/storages/inMemory/InMemoryStorage.js +5 -7
  15. package/cjs/storages/inMemory/InMemoryStorageCS.js +6 -7
  16. package/cjs/storages/inRedis/SplitsCacheInRedis.js +1 -1
  17. package/cjs/storages/inRedis/index.js +9 -13
  18. package/cjs/storages/pluggable/index.js +15 -19
  19. package/cjs/sync/submitters/impressionCountsSubmitter.js +2 -4
  20. package/cjs/sync/submitters/submitterManager.js +3 -6
  21. package/cjs/trackers/impressionsTracker.js +17 -18
  22. package/cjs/trackers/strategy/strategyDebug.js +4 -11
  23. package/cjs/trackers/strategy/strategyNone.js +11 -16
  24. package/cjs/trackers/strategy/strategyOptimized.js +11 -21
  25. package/esm/evaluator/index.js +2 -0
  26. package/esm/evaluator/matchers/large_segment.js +0 -6
  27. package/esm/evaluator/matchers/segment.js +0 -6
  28. package/esm/listeners/browser.js +1 -3
  29. package/esm/readiness/readinessManager.js +6 -0
  30. package/esm/sdkClient/client.js +14 -11
  31. package/esm/sdkClient/sdkClient.js +1 -1
  32. package/esm/sdkFactory/index.js +10 -15
  33. package/esm/sdkManager/index.js +2 -1
  34. package/esm/storages/inLocalStorage/index.js +5 -4
  35. package/esm/storages/inLocalStorage/validateCache.js +1 -2
  36. package/esm/storages/inMemory/InMemoryStorage.js +6 -8
  37. package/esm/storages/inMemory/InMemoryStorageCS.js +7 -8
  38. package/esm/storages/inRedis/SplitsCacheInRedis.js +1 -1
  39. package/esm/storages/inRedis/index.js +10 -14
  40. package/esm/storages/pluggable/index.js +16 -20
  41. package/esm/sync/submitters/impressionCountsSubmitter.js +2 -4
  42. package/esm/sync/submitters/submitterManager.js +3 -6
  43. package/esm/trackers/impressionsTracker.js +17 -18
  44. package/esm/trackers/strategy/strategyDebug.js +4 -11
  45. package/esm/trackers/strategy/strategyNone.js +11 -16
  46. package/esm/trackers/strategy/strategyOptimized.js +11 -21
  47. package/package.json +1 -1
  48. package/src/dtos/types.ts +2 -1
  49. package/src/evaluator/index.ts +2 -0
  50. package/src/evaluator/matchers/large_segment.ts +0 -7
  51. package/src/evaluator/matchers/segment.ts +0 -7
  52. package/src/evaluator/types.ts +1 -1
  53. package/src/listeners/browser.ts +1 -3
  54. package/src/readiness/readinessManager.ts +5 -0
  55. package/src/sdkClient/client.ts +19 -15
  56. package/src/sdkClient/sdkClient.ts +1 -1
  57. package/src/sdkFactory/index.ts +11 -16
  58. package/src/sdkFactory/types.ts +1 -1
  59. package/src/sdkManager/index.ts +2 -1
  60. package/src/storages/inLocalStorage/index.ts +5 -4
  61. package/src/storages/inLocalStorage/validateCache.ts +1 -2
  62. package/src/storages/inMemory/InMemoryStorage.ts +6 -6
  63. package/src/storages/inMemory/InMemoryStorageCS.ts +7 -6
  64. package/src/storages/inRedis/SplitsCacheInRedis.ts +1 -1
  65. package/src/storages/inRedis/index.ts +10 -10
  66. package/src/storages/pluggable/index.ts +16 -20
  67. package/src/storages/types.ts +2 -2
  68. package/src/sync/submitters/impressionCountsSubmitter.ts +2 -4
  69. package/src/sync/submitters/submitterManager.ts +3 -4
  70. package/src/sync/submitters/uniqueKeysSubmitter.ts +2 -3
  71. package/src/trackers/impressionsTracker.ts +18 -19
  72. package/src/trackers/strategy/strategyDebug.ts +4 -11
  73. package/src/trackers/strategy/strategyNone.ts +11 -17
  74. package/src/trackers/strategy/strategyOptimized.ts +10 -20
  75. package/src/trackers/types.ts +13 -8
  76. package/types/splitio.d.ts +4 -0
@@ -5,20 +5,13 @@ exports.strategyDebugFactory = void 0;
5
5
  * Debug strategy for impressions tracker. Wraps impressions to store and adds previousTime if it corresponds
6
6
  *
7
7
  * @param impressionsObserver - impression observer. Previous time (pt property) is included in impression instances
8
- * @returns IStrategyResult
8
+ * @returns Debug strategy
9
9
  */
10
10
  function strategyDebugFactory(impressionsObserver) {
11
11
  return {
12
- process: function (impressions) {
13
- impressions.forEach(function (impression) {
14
- // Adds previous time if it is enabled
15
- impression.pt = impressionsObserver.testAndSet(impression);
16
- });
17
- return {
18
- impressionsToStore: impressions,
19
- impressionsToListener: impressions,
20
- deduped: 0
21
- };
12
+ process: function (impression) {
13
+ impression.pt = impressionsObserver.testAndSet(impression);
14
+ return true;
22
15
  }
23
16
  };
24
17
  }
@@ -4,25 +4,20 @@ exports.strategyNoneFactory = void 0;
4
4
  /**
5
5
  * None strategy for impressions tracker.
6
6
  *
7
- * @param impressionsCounter - cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
7
+ * @param impressionCounts - cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
8
8
  * @param uniqueKeysTracker - unique keys tracker in charge of tracking the unique keys per split.
9
- * @returns IStrategyResult
9
+ * @returns None strategy
10
10
  */
11
- function strategyNoneFactory(impressionsCounter, uniqueKeysTracker) {
11
+ function strategyNoneFactory(impressionCounts, uniqueKeysTracker) {
12
12
  return {
13
- process: function (impressions) {
14
- impressions.forEach(function (impression) {
15
- var now = Date.now();
16
- // Increments impression counter per featureName
17
- impressionsCounter.track(impression.feature, now, 1);
18
- // Keep track by unique key
19
- uniqueKeysTracker.track(impression.keyName, impression.feature);
20
- });
21
- return {
22
- impressionsToStore: [],
23
- impressionsToListener: impressions,
24
- deduped: 0
25
- };
13
+ process: function (impression) {
14
+ var now = Date.now();
15
+ // Increments impression counter per featureName
16
+ impressionCounts.track(impression.feature, now, 1);
17
+ // Keep track by unique key
18
+ uniqueKeysTracker.track(impression.keyName, impression.feature);
19
+ // Do not store impressions
20
+ return false;
26
21
  }
27
22
  };
28
23
  }
@@ -6,29 +6,19 @@ var time_1 = require("../../utils/time");
6
6
  * Optimized strategy for impressions tracker. Wraps impressions to store and adds previousTime if it corresponds
7
7
  *
8
8
  * @param impressionsObserver - impression observer. previous time (pt property) is included in impression instances
9
- * @param impressionsCounter - cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
10
- * @returns IStrategyResult
9
+ * @param impressionCounts - cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
10
+ * @returns Optimized strategy
11
11
  */
12
- function strategyOptimizedFactory(impressionsObserver, impressionsCounter) {
12
+ function strategyOptimizedFactory(impressionsObserver, impressionCounts) {
13
13
  return {
14
- process: function (impressions) {
15
- var impressionsToStore = [];
16
- impressions.forEach(function (impression) {
17
- impression.pt = impressionsObserver.testAndSet(impression);
18
- var now = Date.now();
19
- // Increments impression counter per featureName
20
- if (impression.pt)
21
- impressionsCounter.track(impression.feature, now, 1);
22
- // Checks if the impression should be added in queue to be sent
23
- if (!impression.pt || impression.pt < (0, time_1.truncateTimeFrame)(now)) {
24
- impressionsToStore.push(impression);
25
- }
26
- });
27
- return {
28
- impressionsToStore: impressionsToStore,
29
- impressionsToListener: impressions,
30
- deduped: impressions.length - impressionsToStore.length
31
- };
14
+ process: function (impression) {
15
+ impression.pt = impressionsObserver.testAndSet(impression);
16
+ var now = Date.now();
17
+ // Increments impression counter per featureName
18
+ if (impression.pt)
19
+ impressionCounts.track(impression.feature, now, 1);
20
+ // Checks if the impression should be added in queue to be sent
21
+ return (!impression.pt || impression.pt < (0, time_1.truncateTimeFrame)(now)) ? true : false;
32
22
  }
33
23
  };
34
24
  }
@@ -98,12 +98,14 @@ function getEvaluation(log, splitJSON, key, attributes, storage) {
98
98
  return evaluation.then(function (result) {
99
99
  result.changeNumber = split_1.getChangeNumber();
100
100
  result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
101
+ result.impressionsDisabled = splitJSON.impressionsDisabled;
101
102
  return result;
102
103
  });
103
104
  }
104
105
  else {
105
106
  evaluation.changeNumber = split_1.getChangeNumber(); // Always sync and optional
106
107
  evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
108
+ evaluation.impressionsDisabled = splitJSON.impressionsDisabled;
107
109
  }
108
110
  }
109
111
  return evaluation;
@@ -1,12 +1,6 @@
1
- import { thenable } from '../../utils/promise/thenable';
2
1
  export function largeSegmentMatcherContext(largeSegmentName, storage) {
3
2
  return function largeSegmentMatcher(key) {
4
3
  var isInLargeSegment = storage.largeSegments ? storage.largeSegments.isInSegment(largeSegmentName, key) : false;
5
- if (thenable(isInLargeSegment)) {
6
- isInLargeSegment.then(function (result) {
7
- return result;
8
- });
9
- }
10
4
  return isInLargeSegment;
11
5
  };
12
6
  }
@@ -1,12 +1,6 @@
1
- import { thenable } from '../../utils/promise/thenable';
2
1
  export function segmentMatcherContext(segmentName, storage) {
3
2
  return function segmentMatcher(key) {
4
3
  var isInSegment = storage.segments.isInSegment(segmentName, key);
5
- if (thenable(isInSegment)) {
6
- isInSegment.then(function (result) {
7
- return result;
8
- });
9
- }
10
4
  return isInSegment;
11
5
  };
12
6
  }
@@ -1,6 +1,5 @@
1
1
  import { fromImpressionsCollector } from '../sync/submitters/impressionsSubmitter';
2
2
  import { fromImpressionCountsCollector } from '../sync/submitters/impressionCountsSubmitter';
3
- import { OPTIMIZED, DEBUG, NONE } from '../utils/constants';
4
3
  import { objectAssign } from '../utils/lang/objectAssign';
5
4
  import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
6
5
  import { isConsentGranted } from '../consent';
@@ -60,10 +59,9 @@ var BrowserSignalListener = /** @class */ (function () {
60
59
  var _a = this.settings.urls, events = _a.events, telemetry = _a.telemetry;
61
60
  // Flush impressions & events data if there is user consent
62
61
  if (isConsentGranted(this.settings)) {
63
- var sim = this.settings.sync.impressionsMode;
64
62
  var extraMetadata = {
65
63
  // sim stands for Sync/Split Impressions Mode
66
- sim: sim === OPTIMIZED ? OPTIMIZED : sim === DEBUG ? DEBUG : NONE
64
+ sim: this.settings.sync.impressionsMode
67
65
  };
68
66
  this._flushData(events + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
69
67
  this._flushData(events + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
@@ -1,5 +1,6 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants';
3
+ import { STORAGE_LOCALSTORAGE } from '../utils/constants';
3
4
  function splitsEventEmitterFactory(EventEmitter) {
4
5
  var splitsEventEmitter = objectAssign(new EventEmitter(), {
5
6
  splitsArrived: false,
@@ -80,6 +81,7 @@ export function readinessManagerFactory(EventEmitter, settings, splits, isShared
80
81
  }
81
82
  }
82
83
  function checkIsReadyOrUpdate(diff) {
84
+ var _a;
83
85
  if (isDestroyed)
84
86
  return;
85
87
  if (isReady) {
@@ -98,6 +100,10 @@ export function readinessManagerFactory(EventEmitter, settings, splits, isShared
98
100
  isReady = true;
99
101
  try {
100
102
  syncLastUpdate();
103
+ if (!isReadyFromCache && ((_a = settings.storage) === null || _a === void 0 ? void 0 : _a.type) === STORAGE_LOCALSTORAGE) {
104
+ isReadyFromCache = true;
105
+ gate.emit(SDK_READY_FROM_CACHE);
106
+ }
101
107
  gate.emit(SDK_READY);
102
108
  }
103
109
  catch (e) {
@@ -30,7 +30,7 @@ export function clientFactory(params) {
30
30
  var queue = [];
31
31
  var treatment = processEvaluation(evaluationResult, featureFlagName, key, attributes, withConfig, methodName, queue);
32
32
  impressionsTracker.track(queue, attributes);
33
- stopTelemetryTracker(queue[0] && queue[0].label);
33
+ stopTelemetryTracker(queue[0] && queue[0].imp.label);
34
34
  return treatment;
35
35
  };
36
36
  var evaluation = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
@@ -54,7 +54,7 @@ export function clientFactory(params) {
54
54
  treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, attributes, withConfig, methodName, queue);
55
55
  });
56
56
  impressionsTracker.track(queue, attributes);
57
- stopTelemetryTracker(queue[0] && queue[0].label);
57
+ stopTelemetryTracker(queue[0] && queue[0].imp.label);
58
58
  return treatments;
59
59
  };
60
60
  var evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
@@ -80,7 +80,7 @@ export function clientFactory(params) {
80
80
  treatments[featureFlagName] = processEvaluation(evaluations[featureFlagName], featureFlagName, key, attributes, withConfig, methodName, queue);
81
81
  });
82
82
  impressionsTracker.track(queue, attributes);
83
- stopTelemetryTracker(queue[0] && queue[0].label);
83
+ stopTelemetryTracker(queue[0] && queue[0].imp.label);
84
84
  return treatments;
85
85
  };
86
86
  var evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
@@ -103,18 +103,21 @@ export function clientFactory(params) {
103
103
  function processEvaluation(evaluation, featureFlagName, key, attributes, withConfig, invokingMethodName, queue) {
104
104
  var matchingKey = getMatching(key);
105
105
  var bucketingKey = getBucketing(key);
106
- var treatment = evaluation.treatment, label = evaluation.label, changeNumber = evaluation.changeNumber, _a = evaluation.config, config = _a === void 0 ? null : _a;
106
+ var treatment = evaluation.treatment, label = evaluation.label, changeNumber = evaluation.changeNumber, _a = evaluation.config, config = _a === void 0 ? null : _a, impressionsDisabled = evaluation.impressionsDisabled;
107
107
  log.info(IMPRESSION, [featureFlagName, matchingKey, treatment, label]);
108
108
  if (validateSplitExistence(log, readinessManager, featureFlagName, label, invokingMethodName)) {
109
109
  log.info(IMPRESSION_QUEUEING);
110
110
  queue.push({
111
- feature: featureFlagName,
112
- keyName: matchingKey,
113
- treatment: treatment,
114
- time: Date.now(),
115
- bucketingKey: bucketingKey,
116
- label: label,
117
- changeNumber: changeNumber
111
+ imp: {
112
+ feature: featureFlagName,
113
+ keyName: matchingKey,
114
+ treatment: treatment,
115
+ time: Date.now(),
116
+ bucketingKey: bucketingKey,
117
+ label: label,
118
+ changeNumber: changeNumber,
119
+ },
120
+ disabled: impressionsDisabled
118
121
  });
119
122
  }
120
123
  if (withConfig) {
@@ -47,7 +47,7 @@ export function sdkClientFactory(params, isSharedClient) {
47
47
  releaseApiKey(settings.core.authorizationKey);
48
48
  telemetryTracker.sessionLength();
49
49
  signalListener && signalListener.stop();
50
- uniqueKeysTracker && uniqueKeysTracker.stop();
50
+ uniqueKeysTracker.stop();
51
51
  }
52
52
  // Stop background jobs
53
53
  syncManager && syncManager.stop();
@@ -11,7 +11,7 @@ import { strategyDebugFactory } from '../trackers/strategy/strategyDebug';
11
11
  import { strategyOptimizedFactory } from '../trackers/strategy/strategyOptimized';
12
12
  import { strategyNoneFactory } from '../trackers/strategy/strategyNone';
13
13
  import { uniqueKeysTrackerFactory } from '../trackers/uniqueKeysTracker';
14
- import { NONE, OPTIMIZED } from '../utils/constants';
14
+ import { DEBUG, OPTIMIZED } from '../utils/constants';
15
15
  /**
16
16
  * Modular SDK factory
17
17
  */
@@ -48,19 +48,14 @@ export function sdkFactory(params) {
48
48
  var telemetryTracker = telemetryTrackerFactory(storage.telemetry, platform.now);
49
49
  var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
50
50
  var observer = impressionsObserverFactory();
51
- var uniqueKeysTracker = impressionsMode === NONE ? uniqueKeysTrackerFactory(log, storage.uniqueKeys, filterAdapterFactory && filterAdapterFactory()) : undefined;
52
- var strategy;
53
- switch (impressionsMode) {
54
- case OPTIMIZED:
55
- strategy = strategyOptimizedFactory(observer, storage.impressionCounts);
56
- break;
57
- case NONE:
58
- strategy = strategyNoneFactory(storage.impressionCounts, uniqueKeysTracker);
59
- break;
60
- default:
61
- strategy = strategyDebugFactory(observer);
62
- }
63
- var impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, strategy, whenInit, integrationsManager, storage.telemetry);
51
+ var uniqueKeysTracker = uniqueKeysTrackerFactory(log, storage.uniqueKeys, filterAdapterFactory && filterAdapterFactory());
52
+ var noneStrategy = strategyNoneFactory(storage.impressionCounts, uniqueKeysTracker);
53
+ var strategy = impressionsMode === OPTIMIZED ?
54
+ strategyOptimizedFactory(observer, storage.impressionCounts) :
55
+ impressionsMode === DEBUG ?
56
+ strategyDebugFactory(observer) :
57
+ noneStrategy;
58
+ var impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, noneStrategy, strategy, whenInit, integrationsManager, storage.telemetry);
64
59
  var eventTracker = eventTrackerFactory(settings, storage.events, whenInit, integrationsManager, storage.telemetry);
65
60
  // splitApi is used by SyncManager and Browser signal listener
66
61
  var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
@@ -79,7 +74,7 @@ export function sdkFactory(params) {
79
74
  // We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
80
75
  validateAndTrackApiKey(log, settings.core.authorizationKey);
81
76
  readiness.init();
82
- uniqueKeysTracker && uniqueKeysTracker.start();
77
+ uniqueKeysTracker.start();
83
78
  syncManager && syncManager.start();
84
79
  signalListener && signalListener.start();
85
80
  initCallbacks.forEach(function (cb) { return cb(); });
@@ -25,7 +25,8 @@ function objectToView(splitObject) {
25
25
  treatments: collectTreatments(splitObject),
26
26
  configs: splitObject.configurations || {},
27
27
  sets: splitObject.sets || [],
28
- defaultTreatment: splitObject.defaultTreatment
28
+ defaultTreatment: splitObject.defaultTreatment,
29
+ impressionsDisabled: splitObject.impressionsDisabled === true
29
30
  };
30
31
  }
31
32
  function objectsToViews(splitObjects) {
@@ -8,7 +8,7 @@ import { SplitsCacheInLocal } from './SplitsCacheInLocal';
8
8
  import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
9
9
  import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
10
10
  import { LOG_PREFIX } from './constants';
11
- import { DEBUG, NONE, STORAGE_LOCALSTORAGE } from '../../utils/constants';
11
+ import { STORAGE_LOCALSTORAGE } from '../../utils/constants';
12
12
  import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
13
13
  import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
14
14
  import { getMatching } from '../../utils/key';
@@ -25,7 +25,7 @@ export function InLocalStorage(options) {
25
25
  params.settings.log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
26
26
  return InMemoryStorageCSFactory(params);
27
27
  }
28
- var settings = params.settings, _a = params.settings, log = _a.log, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
28
+ var settings = params.settings, _a = params.settings, log = _a.log, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize;
29
29
  var matchingKey = getMatching(settings.core.key);
30
30
  var keys = new KeyBuilderCS(prefix, matchingKey);
31
31
  var splits = new SplitsCacheInLocal(settings, keys);
@@ -36,10 +36,10 @@ export function InLocalStorage(options) {
36
36
  segments: segments,
37
37
  largeSegments: largeSegments,
38
38
  impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
39
- impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
39
+ impressionCounts: new ImpressionCountsCacheInMemory(),
40
40
  events: new EventsCacheInMemory(eventsQueueSize),
41
41
  telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
42
- uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
42
+ uniqueKeys: new UniqueKeysCacheInMemoryCS(),
43
43
  validateCache: function () {
44
44
  return validateCache(options, settings, keys, splits, segments, largeSegments);
45
45
  },
@@ -54,6 +54,7 @@ export function InLocalStorage(options) {
54
54
  impressionCounts: this.impressionCounts,
55
55
  events: this.events,
56
56
  telemetry: this.telemetry,
57
+ uniqueKeys: this.uniqueKeys,
57
58
  destroy: function () { }
58
59
  };
59
60
  },
@@ -1,7 +1,6 @@
1
1
  import { isFiniteNumber, isNaNNumber } from '../../utils/lang';
2
2
  import { getStorageHash } from '../KeyBuilder';
3
3
  import { LOG_PREFIX } from './constants';
4
- // milliseconds in a day
5
4
  var DEFAULT_CACHE_EXPIRATION_IN_DAYS = 10;
6
5
  var MILLIS_IN_A_DAY = 86400000;
7
6
  /**
@@ -33,7 +32,7 @@ function validateExpiration(options, settings, keys, currentTimestamp, isThereCa
33
32
  log.error(LOG_PREFIX + e);
34
33
  }
35
34
  if (isThereCache) {
36
- log.info(LOG_PREFIX + 'SDK key, flags filter criteria or flags spec version has changed. Cleaning up cache');
35
+ log.info(LOG_PREFIX + 'SDK key, flags filter criteria, or flags spec version has changed. Cleaning up cache');
37
36
  return true;
38
37
  }
39
38
  return false; // No cache to clear
@@ -3,7 +3,7 @@ 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, LOCALHOST_MODE, NONE, STORAGE_MEMORY } from '../../utils/constants';
6
+ import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
7
7
  import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
8
8
  import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
9
9
  /**
@@ -12,17 +12,17 @@ import { UniqueKeysCacheInMemory } from './UniqueKeysCacheInMemory';
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, _c = _a.sync, impressionsMode = _c.impressionsMode, __splitFiltersValidation = _c.__splitFiltersValidation;
15
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
16
16
  var splits = new SplitsCacheInMemory(__splitFiltersValidation);
17
17
  var segments = new SegmentsCacheInMemory();
18
18
  var storage = {
19
19
  splits: splits,
20
20
  segments: segments,
21
21
  impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
22
- impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
22
+ impressionCounts: new ImpressionCountsCacheInMemory(),
23
23
  events: new EventsCacheInMemory(eventsQueueSize),
24
24
  telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
25
- uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemory() : undefined,
25
+ uniqueKeys: new UniqueKeysCacheInMemory(),
26
26
  destroy: function () { }
27
27
  };
28
28
  // @TODO revisit storage logic in localhost mode
@@ -31,10 +31,8 @@ export function InMemoryStorageFactory(params) {
31
31
  var noopTrack = function () { return true; };
32
32
  storage.impressions.track = noopTrack;
33
33
  storage.events.track = noopTrack;
34
- if (storage.impressionCounts)
35
- storage.impressionCounts.track = noopTrack;
36
- if (storage.uniqueKeys)
37
- storage.uniqueKeys.track = noopTrack;
34
+ storage.impressionCounts.track = noopTrack;
35
+ storage.uniqueKeys.track = noopTrack;
38
36
  }
39
37
  return storage;
40
38
  }
@@ -3,7 +3,7 @@ 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, LOCALHOST_MODE, NONE, STORAGE_MEMORY } from '../../utils/constants';
6
+ import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
7
7
  import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
8
8
  import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
9
9
  /**
@@ -12,7 +12,7 @@ import { UniqueKeysCacheInMemoryCS } from './UniqueKeysCacheInMemoryCS';
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, _c = _a.sync, impressionsMode = _c.impressionsMode, __splitFiltersValidation = _c.__splitFiltersValidation;
15
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
16
16
  var splits = new SplitsCacheInMemory(__splitFiltersValidation);
17
17
  var segments = new MySegmentsCacheInMemory();
18
18
  var largeSegments = new MySegmentsCacheInMemory();
@@ -21,10 +21,10 @@ export function InMemoryStorageCSFactory(params) {
21
21
  segments: segments,
22
22
  largeSegments: largeSegments,
23
23
  impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
24
- impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
24
+ impressionCounts: new ImpressionCountsCacheInMemory(),
25
25
  events: new EventsCacheInMemory(eventsQueueSize),
26
26
  telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
27
- uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
27
+ uniqueKeys: new UniqueKeysCacheInMemoryCS(),
28
28
  destroy: function () { },
29
29
  // When using shared instantiation with MEMORY we reuse everything but segments (they are unique per key)
30
30
  shared: function () {
@@ -36,6 +36,7 @@ export function InMemoryStorageCSFactory(params) {
36
36
  impressionCounts: this.impressionCounts,
37
37
  events: this.events,
38
38
  telemetry: this.telemetry,
39
+ uniqueKeys: this.uniqueKeys,
39
40
  destroy: function () { }
40
41
  };
41
42
  },
@@ -46,10 +47,8 @@ export function InMemoryStorageCSFactory(params) {
46
47
  var noopTrack = function () { return true; };
47
48
  storage.impressions.track = noopTrack;
48
49
  storage.events.track = noopTrack;
49
- if (storage.impressionCounts)
50
- storage.impressionCounts.track = noopTrack;
51
- if (storage.uniqueKeys)
52
- storage.uniqueKeys.track = noopTrack;
50
+ storage.impressionCounts.track = noopTrack;
51
+ storage.uniqueKeys.track = noopTrack;
53
52
  }
54
53
  return storage;
55
54
  }
@@ -238,9 +238,9 @@ var SplitsCacheInRedis = /** @class */ (function (_super) {
238
238
  this.log.error(LOG_PREFIX + this.redisError);
239
239
  return Promise.reject(this.redisError);
240
240
  }
241
- var splits = {};
242
241
  var keys = names.map(function (name) { return _this.keys.buildSplitKey(name); });
243
242
  return (_a = this.redis).mget.apply(_a, keys).then(function (splitDefinitions) {
243
+ var splits = {};
244
244
  names.forEach(function (name, idx) {
245
245
  var split = splitDefinitions[idx];
246
246
  splits[name] = split && JSON.parse(split);
@@ -4,7 +4,7 @@ import { SplitsCacheInRedis } from './SplitsCacheInRedis';
4
4
  import { SegmentsCacheInRedis } from './SegmentsCacheInRedis';
5
5
  import { ImpressionsCacheInRedis } from './ImpressionsCacheInRedis';
6
6
  import { EventsCacheInRedis } from './EventsCacheInRedis';
7
- import { DEBUG, NONE, STORAGE_REDIS } from '../../utils/constants';
7
+ import { STORAGE_REDIS } from '../../utils/constants';
8
8
  import { TelemetryCacheInRedis } from './TelemetryCacheInRedis';
9
9
  import { UniqueKeysCacheInRedis } from './UniqueKeysCacheInRedis';
10
10
  import { ImpressionCountsCacheInRedis } from './ImpressionCountsCacheInRedis';
@@ -20,20 +20,18 @@ export function InRedisStorage(options) {
20
20
  var RD = require('./RedisAdapter').RedisAdapter;
21
21
  var prefix = validatePrefix(options.prefix);
22
22
  function InRedisStorageFactory(params) {
23
- var onReadyCb = params.onReadyCb, settings = params.settings, _a = params.settings, log = _a.log, impressionsMode = _a.sync.impressionsMode;
23
+ var onReadyCb = params.onReadyCb, settings = params.settings, log = params.settings.log;
24
24
  var metadata = metadataBuilder(settings);
25
25
  var keys = new KeyBuilderSS(prefix, metadata);
26
26
  var redisClient = new RD(log, options.options || {});
27
27
  var telemetry = new TelemetryCacheInRedis(log, keys, redisClient);
28
- var impressionCountsCache = impressionsMode !== DEBUG ? new ImpressionCountsCacheInRedis(log, keys.buildImpressionsCountKey(), redisClient) : undefined;
29
- var uniqueKeysCache = impressionsMode === NONE ? new UniqueKeysCacheInRedis(log, keys.buildUniqueKeysKey(), redisClient) : undefined;
28
+ var impressionCountsCache = new ImpressionCountsCacheInRedis(log, keys.buildImpressionsCountKey(), redisClient);
29
+ var uniqueKeysCache = new UniqueKeysCacheInRedis(log, keys.buildUniqueKeysKey(), redisClient);
30
30
  // subscription to Redis connect event in order to emit SDK_READY event on consumer mode
31
31
  redisClient.on('connect', function () {
32
32
  onReadyCb();
33
- if (impressionCountsCache)
34
- impressionCountsCache.start();
35
- if (uniqueKeysCache)
36
- uniqueKeysCache.start();
33
+ impressionCountsCache.start();
34
+ uniqueKeysCache.start();
37
35
  // Synchronize config
38
36
  telemetry.recordConfig();
39
37
  });
@@ -48,12 +46,10 @@ export function InRedisStorage(options) {
48
46
  // When using REDIS we should:
49
47
  // 1- Disconnect from the storage
50
48
  destroy: function () {
51
- var promises = [];
52
- if (impressionCountsCache)
53
- promises.push(impressionCountsCache.stop());
54
- if (uniqueKeysCache)
55
- promises.push(uniqueKeysCache.stop());
56
- return Promise.all(promises).then(function () { redisClient.disconnect(); });
49
+ return Promise.all([
50
+ impressionCountsCache.stop(),
51
+ uniqueKeysCache.stop()
52
+ ]).then(function () { redisClient.disconnect(); });
57
53
  // @TODO check that caches works as expected when redisClient is disconnected
58
54
  }
59
55
  };
@@ -7,7 +7,7 @@ import { EventsCachePluggable } from './EventsCachePluggable';
7
7
  import { wrapperAdapter, METHODS_TO_PROMISE_WRAP } from './wrapperAdapter';
8
8
  import { isObject } from '../../utils/lang';
9
9
  import { getStorageHash, validatePrefix } from '../KeyBuilder';
10
- import { CONSUMER_PARTIAL_MODE, DEBUG, NONE, STORAGE_PLUGGABLE } from '../../utils/constants';
10
+ import { CONSUMER_PARTIAL_MODE, STORAGE_PLUGGABLE } from '../../utils/constants';
11
11
  import { ImpressionsCacheInMemory } from '../inMemory/ImpressionsCacheInMemory';
12
12
  import { EventsCacheInMemory } from '../inMemory/EventsCacheInMemory';
13
13
  import { ImpressionCountsCacheInMemory } from '../inMemory/ImpressionCountsCacheInMemory';
@@ -51,30 +51,26 @@ export function PluggableStorage(options) {
51
51
  validatePluggableStorageOptions(options);
52
52
  var prefix = validatePrefix(options.prefix);
53
53
  function PluggableStorageFactory(params) {
54
- var onReadyCb = params.onReadyCb, settings = params.settings, _a = params.settings, log = _a.log, mode = _a.mode, impressionsMode = _a.sync.impressionsMode, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize;
54
+ var onReadyCb = params.onReadyCb, settings = params.settings, _a = params.settings, log = _a.log, mode = _a.mode, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize;
55
55
  var metadata = metadataBuilder(settings);
56
56
  var keys = new KeyBuilderSS(prefix, metadata);
57
57
  var wrapper = wrapperAdapter(log, options.wrapper);
58
- var isSyncronizer = mode === undefined; // If mode is not defined, the synchronizer is running
58
+ var isSynchronizer = mode === undefined; // If mode is not defined, the synchronizer is running
59
59
  var isPartialConsumer = mode === CONSUMER_PARTIAL_MODE;
60
- var telemetry = shouldRecordTelemetry(params) || isSyncronizer ?
60
+ var telemetry = shouldRecordTelemetry(params) || isSynchronizer ?
61
61
  isPartialConsumer ?
62
62
  new TelemetryCacheInMemory() :
63
63
  new TelemetryCachePluggable(log, keys, wrapper) :
64
64
  undefined;
65
- var impressionCountsCache = impressionsMode !== DEBUG || isSyncronizer ?
66
- isPartialConsumer ?
67
- new ImpressionCountsCacheInMemory() :
68
- new ImpressionCountsCachePluggable(log, keys.buildImpressionsCountKey(), wrapper) :
69
- undefined;
70
- var uniqueKeysCache = impressionsMode === NONE || isSyncronizer ?
71
- isPartialConsumer ?
72
- settings.core.key === undefined ? new UniqueKeysCacheInMemory() : new UniqueKeysCacheInMemoryCS() :
73
- new UniqueKeysCachePluggable(log, keys.buildUniqueKeysKey(), wrapper) :
74
- undefined;
65
+ var impressionCountsCache = isPartialConsumer ?
66
+ new ImpressionCountsCacheInMemory() :
67
+ new ImpressionCountsCachePluggable(log, keys.buildImpressionsCountKey(), wrapper);
68
+ var uniqueKeysCache = isPartialConsumer ?
69
+ settings.core.key === undefined ? new UniqueKeysCacheInMemory() : new UniqueKeysCacheInMemoryCS() :
70
+ new UniqueKeysCachePluggable(log, keys.buildUniqueKeysKey(), wrapper);
75
71
  // Connects to wrapper and emits SDK_READY event on main client
76
72
  var connectPromise = wrapper.connect().then(function () {
77
- if (isSyncronizer) {
73
+ if (isSynchronizer) {
78
74
  // @TODO reuse InLocalStorage::validateCache logic
79
75
  // In standalone or producer mode, clear storage if SDK key, flags filter criteria or flags spec version was modified
80
76
  return wrapper.get(keys.buildHashKey()).then(function (hash) {
@@ -91,9 +87,9 @@ export function PluggableStorage(options) {
91
87
  }
92
88
  else {
93
89
  // Start periodic flush of async storages if not running synchronizer (producer mode)
94
- if (impressionCountsCache && impressionCountsCache.start)
90
+ if (impressionCountsCache.start)
95
91
  impressionCountsCache.start();
96
- if (uniqueKeysCache && uniqueKeysCache.start)
92
+ if (uniqueKeysCache.start)
97
93
  uniqueKeysCache.start();
98
94
  if (telemetry && telemetry.recordConfig)
99
95
  telemetry.recordConfig();
@@ -114,9 +110,9 @@ export function PluggableStorage(options) {
114
110
  uniqueKeys: uniqueKeysCache,
115
111
  // Stop periodic flush and disconnect the underlying storage
116
112
  destroy: function () {
117
- return Promise.all(isSyncronizer ? [] : [
118
- impressionCountsCache && impressionCountsCache.stop && impressionCountsCache.stop(),
119
- uniqueKeysCache && uniqueKeysCache.stop && uniqueKeysCache.stop(),
113
+ return Promise.all(isSynchronizer ? [] : [
114
+ impressionCountsCache.stop && impressionCountsCache.stop(),
115
+ uniqueKeysCache.stop && uniqueKeysCache.stop(),
120
116
  ]).then(function () { return wrapper.disconnect(); });
121
117
  },
122
118
  // emits SDK_READY event on shared clients and returns a reference to the storage
@@ -26,8 +26,6 @@ var IMPRESSIONS_COUNT_RATE = 1800000; // 30 minutes
26
26
  */
27
27
  export function impressionCountsSubmitterFactory(params) {
28
28
  var log = params.settings.log, postTestImpressionsCount = params.splitApi.postTestImpressionsCount, impressionCounts = params.storage.impressionCounts;
29
- if (impressionCounts) {
30
- // retry impressions counts only once.
31
- return submitterFactory(log, postTestImpressionsCount, impressionCounts, IMPRESSIONS_COUNT_RATE, 'impression counts', fromImpressionCountsCollector, 1);
32
- }
29
+ // retry impressions counts only once.
30
+ return submitterFactory(log, postTestImpressionsCount, impressionCounts, IMPRESSIONS_COUNT_RATE, 'impression counts', fromImpressionCountsCollector, 1);
33
31
  }