@splitsoftware/splitio-commons 2.0.3-rc.0 → 2.0.3

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 (87) hide show
  1. package/CHANGES.txt +2 -3
  2. package/LICENSE +1 -1
  3. package/README.md +2 -2
  4. package/cjs/evaluator/index.js +0 -2
  5. package/cjs/evaluator/matchers/large_segment.js +0 -6
  6. package/cjs/evaluator/matchers/segment.js +0 -6
  7. package/cjs/listeners/browser.js +6 -4
  8. package/cjs/listeners/node.js +2 -2
  9. package/cjs/sdkClient/client.js +13 -13
  10. package/cjs/sdkClient/sdkClient.js +1 -1
  11. package/cjs/sdkFactory/index.js +14 -9
  12. package/cjs/sdkManager/index.js +1 -2
  13. package/cjs/storages/inLocalStorage/index.js +3 -4
  14. package/cjs/storages/inMemory/InMemoryStorage.js +3 -3
  15. package/cjs/storages/inMemory/InMemoryStorageCS.js +3 -4
  16. package/cjs/storages/inRedis/SplitsCacheInRedis.js +1 -1
  17. package/cjs/storages/inRedis/index.js +13 -9
  18. package/cjs/storages/pluggable/index.js +19 -15
  19. package/cjs/sync/streaming/pushManager.js +8 -6
  20. package/cjs/sync/submitters/impressionCountsSubmitter.js +4 -2
  21. package/cjs/sync/submitters/submitterManager.js +6 -3
  22. package/cjs/sync/syncManagerOnline.js +2 -1
  23. package/cjs/trackers/eventTracker.js +1 -1
  24. package/cjs/trackers/impressionsTracker.js +19 -18
  25. package/cjs/trackers/strategy/strategyDebug.js +11 -4
  26. package/cjs/trackers/strategy/strategyNone.js +16 -11
  27. package/cjs/trackers/strategy/strategyOptimized.js +21 -11
  28. package/cjs/utils/settingsValidation/index.js +1 -1
  29. package/esm/evaluator/index.js +0 -2
  30. package/esm/evaluator/matchers/large_segment.js +0 -6
  31. package/esm/evaluator/matchers/segment.js +0 -6
  32. package/esm/listeners/browser.js +3 -1
  33. package/esm/listeners/node.js +2 -2
  34. package/esm/sdkClient/client.js +13 -13
  35. package/esm/sdkClient/sdkClient.js +1 -1
  36. package/esm/sdkFactory/index.js +15 -10
  37. package/esm/sdkManager/index.js +1 -2
  38. package/esm/storages/inLocalStorage/index.js +4 -5
  39. package/esm/storages/inMemory/InMemoryStorage.js +4 -4
  40. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -5
  41. package/esm/storages/inRedis/SplitsCacheInRedis.js +1 -1
  42. package/esm/storages/inRedis/index.js +14 -10
  43. package/esm/storages/pluggable/index.js +20 -16
  44. package/esm/sync/streaming/pushManager.js +8 -6
  45. package/esm/sync/submitters/impressionCountsSubmitter.js +4 -2
  46. package/esm/sync/submitters/submitterManager.js +6 -3
  47. package/esm/sync/syncManagerOnline.js +2 -1
  48. package/esm/trackers/eventTracker.js +1 -1
  49. package/esm/trackers/impressionsTracker.js +19 -18
  50. package/esm/trackers/strategy/strategyDebug.js +11 -4
  51. package/esm/trackers/strategy/strategyNone.js +16 -11
  52. package/esm/trackers/strategy/strategyOptimized.js +21 -11
  53. package/esm/utils/settingsValidation/index.js +1 -1
  54. package/package.json +1 -1
  55. package/src/dtos/types.ts +1 -2
  56. package/src/evaluator/index.ts +0 -2
  57. package/src/evaluator/matchers/large_segment.ts +0 -7
  58. package/src/evaluator/matchers/segment.ts +0 -7
  59. package/src/evaluator/types.ts +1 -1
  60. package/src/listeners/browser.ts +3 -1
  61. package/src/listeners/node.ts +2 -2
  62. package/src/sdkClient/client.ts +11 -11
  63. package/src/sdkClient/sdkClient.ts +1 -1
  64. package/src/sdkFactory/index.ts +16 -11
  65. package/src/sdkFactory/types.ts +1 -1
  66. package/src/sdkManager/index.ts +1 -2
  67. package/src/storages/inLocalStorage/index.ts +4 -5
  68. package/src/storages/inMemory/InMemoryStorage.ts +4 -4
  69. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -5
  70. package/src/storages/inRedis/SplitsCacheInRedis.ts +1 -1
  71. package/src/storages/inRedis/index.ts +10 -10
  72. package/src/storages/pluggable/index.ts +20 -16
  73. package/src/storages/types.ts +2 -2
  74. package/src/sync/streaming/pushManager.ts +8 -6
  75. package/src/sync/submitters/impressionCountsSubmitter.ts +4 -2
  76. package/src/sync/submitters/submitterManager.ts +4 -3
  77. package/src/sync/submitters/uniqueKeysSubmitter.ts +3 -2
  78. package/src/sync/syncManagerOnline.ts +2 -2
  79. package/src/trackers/eventTracker.ts +1 -1
  80. package/src/trackers/impressionsTracker.ts +19 -18
  81. package/src/trackers/strategy/strategyDebug.ts +11 -4
  82. package/src/trackers/strategy/strategyNone.ts +17 -11
  83. package/src/trackers/strategy/strategyOptimized.ts +20 -10
  84. package/src/trackers/types.ts +8 -2
  85. package/src/utils/settingsValidation/index.ts +1 -1
  86. package/types/index.d.ts +1 -1
  87. package/types/splitio.d.ts +1 -5
@@ -7,37 +7,38 @@ var constants_1 = require("../logger/constants");
7
7
  var constants_2 = require("../utils/constants");
8
8
  /**
9
9
  * Impressions tracker stores impressions in cache and pass them to the listener and integrations manager if provided.
10
+ *
11
+ * @param impressionsCache - cache to save impressions
12
+ * @param metadata - runtime metadata (ip, hostname and version)
13
+ * @param impressionListener - optional impression listener
14
+ * @param integrationsManager - optional integrations manager
15
+ * @param strategy - strategy for impressions tracking.
10
16
  */
11
- function impressionsTrackerFactory(settings, impressionsCache, noneStrategy, strategy, whenInit, integrationsManager, telemetryCache) {
17
+ function impressionsTrackerFactory(settings, impressionsCache, strategy, whenInit, integrationsManager, telemetryCache) {
12
18
  var log = settings.log, impressionListener = settings.impressionListener, _a = settings.runtime, ip = _a.ip, hostname = _a.hostname, version = settings.version;
13
19
  return {
14
20
  track: function (impressions, attributes) {
15
21
  if (settings.userConsent === constants_2.CONSENT_DECLINED)
16
22
  return;
17
- var impressionsToStore = impressions.filter(function (_a) {
18
- var impression = _a[0], track = _a[1];
19
- return track === false ?
20
- noneStrategy.process(impression) :
21
- strategy.process(impression);
22
- });
23
- var impressionsLength = impressions.length;
24
- var impressionsToStoreLength = impressionsToStore.length;
25
- if (impressionsToStoreLength) {
26
- var res = impressionsCache.track(impressionsToStore.map(function (item) { return item[0]; }));
23
+ var impressionsCount = impressions.length;
24
+ var _a = strategy.process(impressions), impressionsToStore = _a.impressionsToStore, impressionsToListener = _a.impressionsToListener, deduped = _a.deduped;
25
+ var impressionsToListenerCount = impressionsToListener.length;
26
+ if (impressionsToStore.length > 0) {
27
+ var res = impressionsCache.track(impressionsToStore);
27
28
  // If we're on an async storage, handle error and log it.
28
29
  if ((0, thenable_1.thenable)(res)) {
29
30
  res.then(function () {
30
- log.info(constants_1.IMPRESSIONS_TRACKER_SUCCESS, [impressionsLength]);
31
+ log.info(constants_1.IMPRESSIONS_TRACKER_SUCCESS, [impressionsCount]);
31
32
  }).catch(function (err) {
32
- log.error(constants_1.ERROR_IMPRESSIONS_TRACKER, [impressionsLength, err]);
33
+ log.error(constants_1.ERROR_IMPRESSIONS_TRACKER, [impressionsCount, err]);
33
34
  });
34
35
  }
35
36
  else {
36
37
  // Record when impressionsCache is sync only (standalone mode)
37
38
  // @TODO we are not dropping impressions on full queue yet, so DROPPED stats are not recorded
38
39
  if (telemetryCache) {
39
- telemetryCache.recordImpressionStats(constants_2.QUEUED, impressionsToStoreLength);
40
- telemetryCache.recordImpressionStats(constants_2.DEDUPED, impressionsLength - impressionsToStoreLength);
40
+ telemetryCache.recordImpressionStats(constants_2.QUEUED, impressionsToStore.length);
41
+ telemetryCache.recordImpressionStats(constants_2.DEDUPED, deduped);
41
42
  }
42
43
  }
43
44
  }
@@ -45,8 +46,8 @@ function impressionsTrackerFactory(settings, impressionsCache, noneStrategy, str
45
46
  if (impressionListener || integrationsManager) {
46
47
  var _loop_1 = function (i) {
47
48
  var impressionData = {
48
- // copy of impression, to avoid unexpected behaviour if modified by integrations or impressionListener
49
- impression: (0, objectAssign_1.objectAssign)({}, impressions[i][0]),
49
+ // copy of impression, to avoid unexpected behavior if modified by integrations or impressionListener
50
+ impression: (0, objectAssign_1.objectAssign)({}, impressionsToListener[i]),
50
51
  attributes: attributes,
51
52
  ip: ip,
52
53
  hostname: hostname,
@@ -68,7 +69,7 @@ function impressionsTrackerFactory(settings, impressionsCache, noneStrategy, str
68
69
  });
69
70
  });
70
71
  };
71
- for (var i = 0; i < impressionsLength; i++) {
72
+ for (var i = 0; i < impressionsToListenerCount; i++) {
72
73
  _loop_1(i);
73
74
  }
74
75
  }
@@ -5,13 +5,20 @@ 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 Debug strategy
8
+ * @returns IStrategyResult
9
9
  */
10
10
  function strategyDebugFactory(impressionsObserver) {
11
11
  return {
12
- process: function (impression) {
13
- impression.pt = impressionsObserver.testAndSet(impression);
14
- return true;
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
+ };
15
22
  }
16
23
  };
17
24
  }
@@ -4,20 +4,25 @@ exports.strategyNoneFactory = void 0;
4
4
  /**
5
5
  * None strategy for impressions tracker.
6
6
  *
7
- * @param impressionCounts - cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
7
+ * @param impressionsCounter - 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 None strategy
9
+ * @returns IStrategyResult
10
10
  */
11
- function strategyNoneFactory(impressionCounts, uniqueKeysTracker) {
11
+ function strategyNoneFactory(impressionsCounter, uniqueKeysTracker) {
12
12
  return {
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;
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
+ };
21
26
  }
22
27
  };
23
28
  }
@@ -6,19 +6,29 @@ 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 impressionCounts - cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
10
- * @returns Optimized strategy
9
+ * @param impressionsCounter - cache to save impressions count. impressions will be deduped (OPTIMIZED mode)
10
+ * @returns IStrategyResult
11
11
  */
12
- function strategyOptimizedFactory(impressionsObserver, impressionCounts) {
12
+ function strategyOptimizedFactory(impressionsObserver, impressionsCounter) {
13
13
  return {
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;
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
+ };
22
32
  }
23
33
  };
24
34
  }
@@ -139,7 +139,7 @@ function settingsValidation(config, validationParams) {
139
139
  withDefaults.core.key = 'localhost_key';
140
140
  }
141
141
  else {
142
- // Keeping same behaviour than JS SDK: if settings key or TT are invalid,
142
+ // Keeping same behavior than JS SDK: if settings key or TT are invalid,
143
143
  // `false` value is used as bound key/TT of the default client, which leads to some issues.
144
144
  // @ts-ignore, @TODO handle invalid keys as a non-recoverable error?
145
145
  withDefaults.core.key = (0, key_1.validateKey)(log, maybeKey, constants_2.LOG_PREFIX_CLIENT_INSTANTIATION);
@@ -98,14 +98,12 @@ 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.track = splitJSON.trackImpressions;
102
101
  return result;
103
102
  });
104
103
  }
105
104
  else {
106
105
  evaluation.changeNumber = split_1.getChangeNumber(); // Always sync and optional
107
106
  evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
108
- evaluation.track = splitJSON.trackImpressions;
109
107
  }
110
108
  }
111
109
  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,5 +1,6 @@
1
1
  import { fromImpressionsCollector } from '../sync/submitters/impressionsSubmitter';
2
2
  import { fromImpressionCountsCollector } from '../sync/submitters/impressionCountsSubmitter';
3
+ import { OPTIMIZED, DEBUG, NONE } from '../utils/constants';
3
4
  import { objectAssign } from '../utils/lang/objectAssign';
4
5
  import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
5
6
  import { isConsentGranted } from '../consent';
@@ -59,9 +60,10 @@ var BrowserSignalListener = /** @class */ (function () {
59
60
  var _a = this.settings.urls, events = _a.events, telemetry = _a.telemetry;
60
61
  // Flush impressions & events data if there is user consent
61
62
  if (isConsentGranted(this.settings)) {
63
+ var sim = this.settings.sync.impressionsMode;
62
64
  var extraMetadata = {
63
65
  // sim stands for Sync/Split Impressions Mode
64
- sim: this.settings.sync.impressionsMode
66
+ sim: sim === OPTIMIZED ? OPTIMIZED : sim === DEBUG ? DEBUG : NONE
65
67
  };
66
68
  this._flushData(events + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
67
69
  this._flushData(events + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
@@ -40,7 +40,7 @@ var NodeSignalListener = /** @class */ (function () {
40
40
  var wrapUp = function () {
41
41
  // Cleaned up, remove handlers.
42
42
  _this.stop();
43
- // This handler prevented the default behaviour, start again.
43
+ // This handler prevented the default behavior, start again.
44
44
  // eslint-disable-next-line no-undef
45
45
  process.kill(process.pid, SIGTERM);
46
46
  };
@@ -53,7 +53,7 @@ var NodeSignalListener = /** @class */ (function () {
53
53
  this.settings.log.error(LOG_PREFIX_CLEANUP + "Error with Split SDK graceful shutdown: " + err);
54
54
  }
55
55
  if (thenable(handlerResult)) {
56
- // Always exit, even with errors. The promise is returned for UT purposses.
56
+ // Always exit, even with errors. The promise is returned for UT purposes.
57
57
  return handlerResult.then(wrapUp).catch(wrapUp);
58
58
  }
59
59
  else {
@@ -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][0].label);
33
+ stopTelemetryTracker(queue[0] && queue[0].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][0].label);
57
+ stopTelemetryTracker(queue[0] && queue[0].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][0].label);
83
+ stopTelemetryTracker(queue[0] && queue[0].label);
84
84
  return treatments;
85
85
  };
86
86
  var evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
@@ -103,19 +103,19 @@ 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, track = evaluation.track;
106
+ var treatment = evaluation.treatment, label = evaluation.label, changeNumber = evaluation.changeNumber, _a = evaluation.config, config = _a === void 0 ? null : _a;
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
- queue.push([{
111
- feature: featureFlagName,
112
- keyName: matchingKey,
113
- treatment: treatment,
114
- time: Date.now(),
115
- bucketingKey: bucketingKey,
116
- label: label,
117
- changeNumber: changeNumber,
118
- }, track]);
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
118
+ });
119
119
  }
120
120
  if (withConfig) {
121
121
  return {
@@ -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.stop();
50
+ uniqueKeysTracker && 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 { DEBUG, OPTIMIZED } from '../utils/constants';
14
+ import { NONE, OPTIMIZED } from '../utils/constants';
15
15
  /**
16
16
  * Modular SDK factory
17
17
  */
@@ -48,14 +48,19 @@ 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 = 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);
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);
59
64
  var eventTracker = eventTrackerFactory(settings, storage.events, whenInit, integrationsManager, storage.telemetry);
60
65
  // splitApi is used by SyncManager and Browser signal listener
61
66
  var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
@@ -74,7 +79,7 @@ export function sdkFactory(params) {
74
79
  // We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
75
80
  validateAndTrackApiKey(log, settings.core.authorizationKey);
76
81
  readiness.init();
77
- uniqueKeysTracker.start();
82
+ uniqueKeysTracker && uniqueKeysTracker.start();
78
83
  syncManager && syncManager.start();
79
84
  signalListener && signalListener.start();
80
85
  initCallbacks.forEach(function (cb) { return cb(); });
@@ -25,8 +25,7 @@ function objectToView(splitObject) {
25
25
  treatments: collectTreatments(splitObject),
26
26
  configs: splitObject.configurations || {},
27
27
  sets: splitObject.sets || [],
28
- defaultTreatment: splitObject.defaultTreatment,
29
- trackImpressions: splitObject.trackImpressions !== false
28
+ defaultTreatment: splitObject.defaultTreatment
30
29
  };
31
30
  }
32
31
  function objectsToViews(splitObjects) {
@@ -9,7 +9,7 @@ import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
9
9
  import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
10
10
  import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
11
11
  import { LOG_PREFIX } from './constants';
12
- import { STORAGE_LOCALSTORAGE } from '../../utils/constants';
12
+ import { DEBUG, NONE, STORAGE_LOCALSTORAGE } from '../../utils/constants';
13
13
  import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
14
14
  import { UniqueKeysCacheInMemoryCS } from '../inMemory/UniqueKeysCacheInMemoryCS';
15
15
  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;
28
+ var settings = params.settings, _a = params.settings, log = _a.log, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
29
29
  var matchingKey = getMatching(settings.core.key);
30
30
  var keys = new KeyBuilderCS(prefix, matchingKey);
31
31
  var expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
@@ -37,10 +37,10 @@ export function InLocalStorage(options) {
37
37
  segments: segments,
38
38
  largeSegments: largeSegments,
39
39
  impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
40
- impressionCounts: new ImpressionCountsCacheInMemory(),
40
+ impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
41
41
  events: new EventsCacheInMemory(eventsQueueSize),
42
42
  telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
43
- uniqueKeys: new UniqueKeysCacheInMemoryCS(),
43
+ uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
44
44
  destroy: function () { },
45
45
  // When using shared instantiation with MEMORY we reuse everything but segments (they are customer per key).
46
46
  shared: function (matchingKey) {
@@ -52,7 +52,6 @@ export function InLocalStorage(options) {
52
52
  impressionCounts: this.impressionCounts,
53
53
  events: this.events,
54
54
  telemetry: this.telemetry,
55
- uniqueKeys: this.uniqueKeys,
56
55
  destroy: function () { }
57
56
  };
58
57
  },
@@ -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 { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
6
+ import { DEBUG, LOCALHOST_MODE, NONE, 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, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
15
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, _c = _a.sync, impressionsMode = _c.impressionsMode, __splitFiltersValidation = _c.__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: new ImpressionCountsCacheInMemory(),
22
+ impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
23
23
  events: new EventsCacheInMemory(eventsQueueSize),
24
24
  telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
25
- uniqueKeys: new UniqueKeysCacheInMemory(),
25
+ uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemory() : undefined,
26
26
  destroy: function () { }
27
27
  };
28
28
  // @TODO revisit storage logic in localhost mode
@@ -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 { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
6
+ import { DEBUG, LOCALHOST_MODE, NONE, 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, __splitFiltersValidation = _a.sync.__splitFiltersValidation;
15
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, _c = _a.sync, impressionsMode = _c.impressionsMode, __splitFiltersValidation = _c.__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: new ImpressionCountsCacheInMemory(),
24
+ impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
25
25
  events: new EventsCacheInMemory(eventsQueueSize),
26
26
  telemetry: shouldRecordTelemetry(params) ? new TelemetryCacheInMemory(splits, segments) : undefined,
27
- uniqueKeys: new UniqueKeysCacheInMemoryCS(),
27
+ uniqueKeys: impressionsMode === NONE ? new UniqueKeysCacheInMemoryCS() : undefined,
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,7 +36,6 @@ export function InMemoryStorageCSFactory(params) {
36
36
  impressionCounts: this.impressionCounts,
37
37
  events: this.events,
38
38
  telemetry: this.telemetry,
39
- uniqueKeys: this.uniqueKeys,
40
39
  destroy: function () { }
41
40
  };
42
41
  },
@@ -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 { STORAGE_REDIS } from '../../utils/constants';
7
+ import { DEBUG, NONE, STORAGE_REDIS } from '../../utils/constants';
8
8
  import { TelemetryCacheInRedis } from './TelemetryCacheInRedis';
9
9
  import { UniqueKeysCacheInRedis } from './UniqueKeysCacheInRedis';
10
10
  import { ImpressionCountsCacheInRedis } from './ImpressionCountsCacheInRedis';
@@ -20,18 +20,20 @@ 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, log = params.settings.log;
23
+ var onReadyCb = params.onReadyCb, settings = params.settings, _a = params.settings, log = _a.log, impressionsMode = _a.sync.impressionsMode;
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 = new ImpressionCountsCacheInRedis(log, keys.buildImpressionsCountKey(), redisClient);
29
- var uniqueKeysCache = new UniqueKeysCacheInRedis(log, keys.buildUniqueKeysKey(), 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;
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
- impressionCountsCache.start();
34
- uniqueKeysCache.start();
33
+ if (impressionCountsCache)
34
+ impressionCountsCache.start();
35
+ if (uniqueKeysCache)
36
+ uniqueKeysCache.start();
35
37
  // Synchronize config
36
38
  telemetry.recordConfig();
37
39
  });
@@ -46,10 +48,12 @@ export function InRedisStorage(options) {
46
48
  // When using REDIS we should:
47
49
  // 1- Disconnect from the storage
48
50
  destroy: function () {
49
- return Promise.all([
50
- impressionCountsCache.stop(),
51
- uniqueKeysCache.stop()
52
- ]).then(function () { redisClient.disconnect(); });
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(); });
53
57
  // @TODO check that caches works as expected when redisClient is disconnected
54
58
  }
55
59
  };