@splitsoftware/splitio-commons 1.6.2-rc.9 → 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.
Files changed (176) hide show
  1. package/CHANGES.txt +3 -1
  2. package/cjs/consent/sdkUserConsent.js +2 -2
  3. package/cjs/listeners/browser.js +11 -12
  4. package/cjs/logger/constants.js +2 -1
  5. package/cjs/sdkClient/sdkClient.js +3 -1
  6. package/cjs/sdkFactory/index.js +26 -26
  7. package/cjs/services/splitApi.js +20 -0
  8. package/cjs/storages/AbstractSplitsCacheAsync.js +1 -1
  9. package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
  10. package/cjs/storages/KeyBuilderSS.js +10 -43
  11. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -1
  12. package/cjs/storages/inLocalStorage/index.js +17 -9
  13. package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +12 -1
  14. package/cjs/storages/inMemory/InMemoryStorage.js +13 -6
  15. package/cjs/storages/inMemory/InMemoryStorageCS.js +13 -6
  16. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +60 -35
  17. package/cjs/storages/inMemory/UniqueKeysCacheInMemory.js +72 -0
  18. package/cjs/storages/inMemory/UniqueKeysCacheInMemoryCS.js +76 -0
  19. package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +85 -0
  20. package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
  21. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +4 -4
  22. package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +71 -0
  23. package/cjs/storages/inRedis/constants.js +4 -1
  24. package/cjs/storages/inRedis/index.js +20 -3
  25. package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +81 -0
  26. package/cjs/storages/pluggable/ImpressionsCachePluggable.js +2 -19
  27. package/cjs/storages/pluggable/TelemetryCachePluggable.js +4 -4
  28. package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +61 -0
  29. package/cjs/storages/pluggable/inMemoryWrapper.js +8 -6
  30. package/cjs/storages/pluggable/index.js +38 -9
  31. package/cjs/storages/utils.js +73 -0
  32. package/cjs/sync/submitters/submitterManager.js +3 -0
  33. package/cjs/sync/submitters/telemetrySubmitter.js +5 -40
  34. package/cjs/sync/submitters/uniqueKeysSubmitter.js +27 -0
  35. package/cjs/trackers/impressionObserver/utils.js +1 -17
  36. package/cjs/trackers/impressionsTracker.js +22 -41
  37. package/cjs/trackers/strategy/strategyDebug.js +25 -0
  38. package/cjs/trackers/strategy/strategyNone.js +29 -0
  39. package/cjs/trackers/strategy/strategyOptimized.js +35 -0
  40. package/cjs/trackers/uniqueKeysTracker.js +38 -0
  41. package/cjs/utils/constants/index.js +4 -2
  42. package/cjs/utils/redis/RedisMock.js +31 -0
  43. package/cjs/utils/settingsValidation/impressionsMode.js +2 -2
  44. package/cjs/utils/settingsValidation/index.js +7 -1
  45. package/esm/consent/sdkUserConsent.js +2 -2
  46. package/esm/listeners/browser.js +12 -13
  47. package/esm/logger/constants.js +1 -0
  48. package/esm/sdkClient/sdkClient.js +3 -1
  49. package/esm/sdkFactory/index.js +26 -26
  50. package/esm/services/splitApi.js +20 -0
  51. package/esm/storages/AbstractSplitsCacheAsync.js +1 -1
  52. package/esm/storages/AbstractSplitsCacheSync.js +1 -1
  53. package/esm/storages/KeyBuilderSS.js +7 -37
  54. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -1
  55. package/esm/storages/inLocalStorage/index.js +18 -10
  56. package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +12 -1
  57. package/esm/storages/inMemory/InMemoryStorage.js +14 -7
  58. package/esm/storages/inMemory/InMemoryStorageCS.js +14 -7
  59. package/esm/storages/inMemory/TelemetryCacheInMemory.js +61 -36
  60. package/esm/storages/inMemory/UniqueKeysCacheInMemory.js +68 -0
  61. package/esm/storages/inMemory/UniqueKeysCacheInMemoryCS.js +73 -0
  62. package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +82 -0
  63. package/esm/storages/inRedis/ImpressionsCacheInRedis.js +2 -19
  64. package/esm/storages/inRedis/TelemetryCacheInRedis.js +1 -1
  65. package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +68 -0
  66. package/esm/storages/inRedis/constants.js +3 -0
  67. package/esm/storages/inRedis/index.js +21 -4
  68. package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +78 -0
  69. package/esm/storages/pluggable/ImpressionsCachePluggable.js +2 -19
  70. package/esm/storages/pluggable/TelemetryCachePluggable.js +1 -1
  71. package/esm/storages/pluggable/UniqueKeysCachePluggable.js +58 -0
  72. package/esm/storages/pluggable/inMemoryWrapper.js +8 -6
  73. package/esm/storages/pluggable/index.js +39 -10
  74. package/esm/storages/utils.js +65 -0
  75. package/esm/sync/submitters/submitterManager.js +3 -0
  76. package/esm/sync/submitters/telemetrySubmitter.js +5 -39
  77. package/esm/sync/submitters/uniqueKeysSubmitter.js +23 -0
  78. package/esm/trackers/impressionObserver/utils.js +1 -15
  79. package/esm/trackers/impressionsTracker.js +22 -41
  80. package/esm/trackers/strategy/strategyDebug.js +21 -0
  81. package/esm/trackers/strategy/strategyNone.js +25 -0
  82. package/esm/trackers/strategy/strategyOptimized.js +31 -0
  83. package/esm/trackers/uniqueKeysTracker.js +34 -0
  84. package/esm/utils/constants/index.js +2 -0
  85. package/esm/utils/redis/RedisMock.js +28 -0
  86. package/esm/utils/settingsValidation/impressionsMode.js +3 -3
  87. package/esm/utils/settingsValidation/index.js +7 -1
  88. package/package.json +1 -2
  89. package/src/consent/sdkUserConsent.ts +2 -2
  90. package/src/listeners/browser.ts +12 -15
  91. package/src/logger/constants.ts +1 -0
  92. package/src/sdkClient/sdkClient.ts +3 -1
  93. package/src/sdkFactory/index.ts +29 -31
  94. package/src/sdkFactory/types.ts +7 -4
  95. package/src/services/splitApi.ts +22 -0
  96. package/src/services/types.ts +6 -0
  97. package/src/storages/AbstractSplitsCacheAsync.ts +1 -1
  98. package/src/storages/AbstractSplitsCacheSync.ts +1 -1
  99. package/src/storages/KeyBuilderSS.ts +9 -43
  100. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +0 -1
  101. package/src/storages/inLocalStorage/index.ts +18 -10
  102. package/src/storages/inMemory/AttributesCacheInMemory.ts +7 -7
  103. package/src/storages/inMemory/ImpressionCountsCacheInMemory.ts +16 -1
  104. package/src/storages/inMemory/InMemoryStorage.ts +14 -7
  105. package/src/storages/inMemory/InMemoryStorageCS.ts +14 -7
  106. package/src/storages/inMemory/TelemetryCacheInMemory.ts +69 -34
  107. package/src/storages/inMemory/UniqueKeysCacheInMemory.ts +80 -0
  108. package/src/storages/inMemory/UniqueKeysCacheInMemoryCS.ts +86 -0
  109. package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +95 -0
  110. package/src/storages/inRedis/ImpressionsCacheInRedis.ts +2 -22
  111. package/src/storages/inRedis/TelemetryCacheInRedis.ts +3 -2
  112. package/src/storages/inRedis/UniqueKeysCacheInRedis.ts +77 -0
  113. package/src/storages/inRedis/constants.ts +3 -0
  114. package/src/storages/inRedis/index.ts +18 -5
  115. package/src/storages/pluggable/ImpressionCountsCachePluggable.ts +92 -0
  116. package/src/storages/pluggable/ImpressionsCachePluggable.ts +3 -23
  117. package/src/storages/pluggable/TelemetryCachePluggable.ts +3 -2
  118. package/src/storages/pluggable/UniqueKeysCachePluggable.ts +67 -0
  119. package/src/storages/pluggable/inMemoryWrapper.ts +6 -6
  120. package/src/storages/pluggable/index.ts +41 -9
  121. package/src/storages/types.ts +56 -55
  122. package/src/storages/utils.ts +78 -0
  123. package/src/sync/submitters/submitter.ts +2 -2
  124. package/src/sync/submitters/submitterManager.ts +2 -0
  125. package/src/sync/submitters/telemetrySubmitter.ts +8 -43
  126. package/src/sync/submitters/types.ts +29 -27
  127. package/src/sync/submitters/uniqueKeysSubmitter.ts +36 -0
  128. package/src/trackers/impressionObserver/utils.ts +1 -16
  129. package/src/trackers/impressionsTracker.ts +25 -46
  130. package/src/trackers/strategy/strategyDebug.ts +28 -0
  131. package/src/trackers/strategy/strategyNone.ts +34 -0
  132. package/src/trackers/strategy/strategyOptimized.ts +42 -0
  133. package/src/trackers/types.ts +28 -0
  134. package/src/trackers/uniqueKeysTracker.ts +48 -0
  135. package/src/types.ts +1 -1
  136. package/src/utils/constants/index.ts +2 -0
  137. package/src/utils/redis/RedisMock.ts +33 -0
  138. package/src/utils/settingsValidation/impressionsMode.ts +3 -3
  139. package/src/utils/settingsValidation/index.ts +5 -1
  140. package/types/logger/constants.d.ts +1 -0
  141. package/types/sdkFactory/types.d.ts +4 -2
  142. package/types/services/types.d.ts +4 -0
  143. package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
  144. package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
  145. package/types/storages/KeyBuilderSS.d.ts +3 -3
  146. package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +0 -1
  147. package/types/storages/inMemory/ImpressionCountsCacheInMemory.d.ts +5 -1
  148. package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +20 -9
  149. package/types/storages/inMemory/uniqueKeysCacheInMemory.d.ts +35 -0
  150. package/types/storages/inMemory/uniqueKeysCacheInMemoryCS.d.ts +35 -0
  151. package/types/storages/inRedis/ImpressionCountsCacheInRedis.d.ts +16 -0
  152. package/types/storages/inRedis/ImpressionsCacheInRedis.d.ts +0 -1
  153. package/types/storages/inRedis/constants.d.ts +3 -0
  154. package/types/storages/inRedis/uniqueKeysCacheInRedis.d.ts +21 -0
  155. package/types/storages/pluggable/ImpressionCountsCachePluggable.d.ts +16 -0
  156. package/types/storages/pluggable/ImpressionsCachePluggable.d.ts +1 -2
  157. package/types/storages/pluggable/UniqueKeysCachePluggable.d.ts +20 -0
  158. package/types/storages/types.d.ts +39 -38
  159. package/types/storages/utils.d.ts +8 -0
  160. package/types/sync/submitters/submitter.d.ts +2 -2
  161. package/types/sync/submitters/telemetrySubmitter.d.ts +2 -10
  162. package/types/sync/submitters/types.d.ts +27 -7
  163. package/types/sync/submitters/uniqueKeysSubmitter.d.ts +5 -0
  164. package/types/trackers/impressionObserver/utils.d.ts +0 -8
  165. package/types/trackers/impressionsTracker.d.ts +4 -6
  166. package/types/trackers/strategy/strategyDebug.d.ts +9 -0
  167. package/types/trackers/strategy/strategyNone.d.ts +10 -0
  168. package/types/trackers/strategy/strategyOptimized.d.ts +11 -0
  169. package/types/trackers/types.d.ts +23 -0
  170. package/types/trackers/uniqueKeysTracker.d.ts +13 -0
  171. package/types/types.d.ts +1 -1
  172. package/types/utils/constants/index.d.ts +2 -0
  173. package/types/utils/redis/RedisMock.d.ts +4 -0
  174. package/cjs/storages/metadataBuilder.js +0 -12
  175. package/esm/storages/metadataBuilder.js +0 -8
  176. package/src/storages/metadataBuilder.ts +0 -11
package/CHANGES.txt CHANGED
@@ -1,6 +1,8 @@
1
- 1.7.0 (September XXX, 2022)
1
+ 1.7.0 (October 4, 2022)
2
+ - Added a new impressions mode for the SDK called NONE, to be used in factory when there is no desire to capture impressions on an SDK factory to feed Split's analytics engine. Running NONE mode, the SDK will only capture unique keys evaluated for a particular feature flag instead of full blown impressions.
2
3
  - Updated SDK telemetry to support pluggable storage, partial consumer mode, and synchronizer.
3
4
  - Updated storage implementations to improve the performance of split evaluations (i.e., `getTreatment(s)` method calls) when using the default storage in memory.
5
+ - Updated evaluation flow to avoid unnecessarily storage calls when the SDK is not ready.
4
6
 
5
7
  1.6.1 (July 22, 2022)
6
8
  - Updated GoogleAnalyticsToSplit integration to validate `autoRequire` config parameter and avoid some wrong warning logs when mapping GA hit fields to Split event properties.
@@ -39,8 +39,8 @@ function createUserConsentAPI(params) {
39
39
  if (events.clear)
40
40
  events.clear(); // @ts-ignore
41
41
  if (impressions.clear)
42
- impressions.clear();
43
- if (impressionCounts)
42
+ impressions.clear(); // @ts-ignore
43
+ if (impressionCounts && impressionCounts.clear)
44
44
  impressionCounts.clear();
45
45
  }
46
46
  }
@@ -7,7 +7,6 @@ var constants_1 = require("../utils/constants");
7
7
  var objectAssign_1 = require("../utils/lang/objectAssign");
8
8
  var constants_2 = require("../logger/constants");
9
9
  var consent_1 = require("../consent");
10
- var telemetrySubmitter_1 = require("../sync/submitters/telemetrySubmitter");
11
10
  var VISIBILITYCHANGE_EVENT = 'visibilitychange';
12
11
  var PAGEHIDE_EVENT = 'pagehide';
13
12
  var UNLOAD_EVENT = 'unload';
@@ -71,24 +70,25 @@ var BrowserSignalListener = /** @class */ (function () {
71
70
  BrowserSignalListener.prototype.flushData = function () {
72
71
  if (!this.syncManager)
73
72
  return; // In consumer mode there is not sync manager and data to flush
73
+ var _a = this.settings.urls, events = _a.events, telemetry = _a.telemetry;
74
74
  // Flush impressions & events data if there is user consent
75
75
  if ((0, consent_1.isConsentGranted)(this.settings)) {
76
- var eventsUrl = this.settings.urls.events;
76
+ var sim = this.settings.sync.impressionsMode;
77
77
  var extraMetadata = {
78
78
  // sim stands for Sync/Split Impressions Mode
79
- sim: this.settings.sync.impressionsMode === constants_1.OPTIMIZED ? constants_1.OPTIMIZED : constants_1.DEBUG
79
+ sim: sim === constants_1.OPTIMIZED ? constants_1.OPTIMIZED : sim === constants_1.DEBUG ? constants_1.DEBUG : constants_1.NONE
80
80
  };
81
- this._flushData(eventsUrl + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
82
- this._flushData(eventsUrl + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
81
+ this._flushData(events + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
82
+ this._flushData(events + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
83
83
  if (this.storage.impressionCounts)
84
- this._flushData(eventsUrl + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, impressionCountsSubmitter_1.fromImpressionCountsCollector);
84
+ this._flushData(events + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, impressionCountsSubmitter_1.fromImpressionCountsCollector);
85
+ // @ts-ignore
86
+ if (this.storage.uniqueKeys)
87
+ this._flushData(telemetry + '/v1/keys/cs/beacon', this.storage.uniqueKeys, this.serviceApi.postUniqueKeysBulkCs);
85
88
  }
86
89
  // Flush telemetry data
87
- if (this.storage.telemetry) {
88
- var telemetryUrl = this.settings.urls.telemetry;
89
- var telemetryCacheAdapter = (0, telemetrySubmitter_1.telemetryCacheStatsAdapter)(this.storage.telemetry, this.storage.splits, this.storage.segments);
90
- this._flushData(telemetryUrl + '/v1/metrics/usage/beacon', telemetryCacheAdapter, this.serviceApi.postMetricsUsage);
91
- }
90
+ if (this.storage.telemetry)
91
+ this._flushData(telemetry + '/v1/metrics/usage/beacon', this.storage.telemetry, this.serviceApi.postMetricsUsage);
92
92
  };
93
93
  BrowserSignalListener.prototype.flushDataIfHidden = function () {
94
94
  // Precondition: document defined
@@ -102,7 +102,6 @@ var BrowserSignalListener = /** @class */ (function () {
102
102
  if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
103
103
  postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible exception
104
104
  }
105
- cache.clear();
106
105
  }
107
106
  };
108
107
  /**
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SYNC_SPLITS_FETCH_RETRY = exports.POLLING_STOP = exports.POLLING_START = exports.POLLING_SMART_PAUSING = exports.NEW_FACTORY = exports.NEW_SHARED_CLIENT = exports.IMPRESSION_QUEUEING = exports.IMPRESSION = exports.CLIENT_READY = exports.CLIENT_READY_FROM_CACHE = exports.SETTINGS_SPLITS_FILTER = exports.SYNC_TASK_STOP = exports.SYNC_TASK_EXECUTE = exports.SYNC_TASK_START = exports.STREAMING_NEW_MESSAGE = exports.SYNC_SPLITS_SEGMENTS = exports.SYNC_SPLITS_REMOVED = exports.SYNC_SPLITS_NEW = exports.SYNC_SPLITS_FETCH = exports.SYNC_OFFLINE_DATA = exports.RETRIEVE_MANAGER = exports.RETRIEVE_CLIENT_EXISTING = exports.RETRIEVE_CLIENT_DEFAULT = exports.CLEANUP_DEREGISTERING = exports.CLEANUP_REGISTERING = exports.ENGINE_SANITIZE = exports.ENGINE_VALUE = exports.ENGINE_MATCHER_WHITELIST = exports.ENGINE_MATCHER_STARTS_WITH = exports.ENGINE_MATCHER_STRING_INVALID = exports.ENGINE_MATCHER_STRING = exports.ENGINE_MATCHER_SEGMENT = exports.ENGINE_MATCHER_PART_OF = exports.ENGINE_MATCHER_LESS = exports.ENGINE_MATCHER_GREATER = exports.ENGINE_MATCHER_ENDS_WITH = exports.ENGINE_MATCHER_EQUAL_TO_SET = exports.ENGINE_MATCHER_EQUAL = exports.ENGINE_MATCHER_DEPENDENCY_PRE = exports.ENGINE_MATCHER_DEPENDENCY = exports.ENGINE_MATCHER_CONTAINS_STRING = exports.ENGINE_MATCHER_CONTAINS_ANY = exports.ENGINE_MATCHER_CONTAINS_ALL = exports.ENGINE_MATCHER_BOOLEAN = exports.ENGINE_MATCHER_BETWEEN = exports.ENGINE_MATCHER_ALL = exports.ENGINE_BUCKET = exports.ENGINE_COMBINER_IFELSEIF_NO_TREATMENT = exports.ENGINE_COMBINER_IFELSEIF = exports.ENGINE_COMBINER_AND = void 0;
4
4
  exports.ERROR_EVENT_TYPE_FORMAT = exports.ERROR_EVENTS_TRACKER = exports.ERROR_IMPRESSIONS_LISTENER = exports.ERROR_IMPRESSIONS_TRACKER = exports.ERROR_STREAMING_AUTH = exports.ERROR_STREAMING_SSE = exports.ERROR_SYNC_OFFLINE_LOADING = exports.ERROR_CLIENT_CANNOT_GET_READY = exports.ERROR_CLIENT_LISTENER = exports.ERROR_LOGLEVEL_INVALID = exports.ERROR_ENGINE_COMBINER_IFELSEIF = exports.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = exports.WARN_API_KEY = exports.WARN_SPLITS_FILTER_EMPTY = exports.WARN_SPLITS_FILTER_INVALID = exports.WARN_SPLITS_FILTER_IGNORED = exports.WARN_INTEGRATION_INVALID = exports.WARN_NOT_EXISTENT_TT = exports.WARN_LOWERCASE_TRAFFIC_TYPE = exports.WARN_NOT_EXISTENT_SPLIT = exports.WARN_TRIMMING = exports.WARN_CONVERTING = exports.WARN_TRIMMING_PROPERTIES = exports.WARN_SETTING_NULL = exports.SUBMITTERS_PUSH_RETRY = exports.SUBMITTERS_PUSH_FAILS = exports.STREAMING_FALLBACK = exports.STREAMING_PARSING_MESSAGE_FAILS = exports.STREAMING_PARSING_ERROR_FAILS = exports.SYNC_SPLITS_FETCH_FAILS = exports.SYNC_MYSEGMENTS_FETCH_RETRY = exports.CLIENT_NOT_READY = exports.CLIENT_NO_LISTENER = exports.ENGINE_VALUE_NO_ATTRIBUTES = exports.ENGINE_VALUE_INVALID = exports.USER_CONSENT_INITIAL = exports.USER_CONSENT_NOT_UPDATED = exports.USER_CONSENT_UPDATED = exports.IMPRESSIONS_TRACKER_SUCCESS = exports.EVENTS_TRACKER_SUCCESS = exports.SYNC_STOP_POLLING = exports.SYNC_CONTINUE_POLLING = exports.SYNC_START_POLLING = exports.SUBMITTERS_PUSH = exports.SUBMITTERS_PUSH_FULL_QUEUE = exports.STREAMING_DISCONNECTING = exports.STREAMING_DISABLED = exports.STREAMING_CONNECTING = exports.STREAMING_RECONNECT = exports.STREAMING_REFRESH_TOKEN = void 0;
5
- exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ERROR_MIN_CONFIG_PARAM = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_LOCALHOST_MODULE_REQUIRED = exports.ERROR_HTTP = exports.ERROR_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = exports.ERROR_SIZE_EXCEEDED = exports.ERROR_NOT_PLAIN_OBJECT = void 0;
5
+ exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_UNIQUE_KEYS_TRACKER = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ERROR_MIN_CONFIG_PARAM = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_LOCALHOST_MODULE_REQUIRED = exports.ERROR_HTTP = exports.ERROR_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = exports.ERROR_SIZE_EXCEEDED = exports.ERROR_NOT_PLAIN_OBJECT = void 0;
6
6
  /**
7
7
  * Message codes used to trim string log messages from commons and client-side API modules,
8
8
  * in order to reduce the minimal SDK size for Browser and eventually other client-side environments.
@@ -144,4 +144,5 @@ exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC + ':polling-manager: '
144
144
  exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC + ':submitter: ';
145
145
  exports.LOG_PREFIX_IMPRESSIONS_TRACKER = 'impressions-tracker: ';
146
146
  exports.LOG_PREFIX_EVENTS_TRACKER = 'events-tracker: ';
147
+ exports.LOG_PREFIX_UNIQUE_KEYS_TRACKER = 'unique-keys-tracker: ';
147
148
  exports.LOG_PREFIX_CLEANUP = 'cleanup: ';
@@ -9,7 +9,7 @@ var clientInputValidation_1 = require("./clientInputValidation");
9
9
  * Creates an Sdk client, i.e., a base client with status and destroy interface
10
10
  */
11
11
  function sdkClientFactory(params, isSharedClient) {
12
- var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings, telemetryTracker = params.telemetryTracker;
12
+ var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings, telemetryTracker = params.telemetryTracker, uniqueKeysTracker = params.uniqueKeysTracker;
13
13
  return (0, objectAssign_1.objectAssign)(
14
14
  // Proto-linkage of the readiness Event Emitter
15
15
  Object.create(sdkReadinessManager.sdkStatus),
@@ -31,6 +31,8 @@ function sdkClientFactory(params, isSharedClient) {
31
31
  // Release the API Key if it is the main client
32
32
  if (!isSharedClient)
33
33
  (0, apiKey_1.releaseApiKey)(settings.core.authorizationKey);
34
+ if (uniqueKeysTracker)
35
+ uniqueKeysTracker.stop();
34
36
  // Cleanup storage
35
37
  return storage.destroy();
36
38
  });
@@ -5,58 +5,58 @@ var sdkReadinessManager_1 = require("../readiness/sdkReadinessManager");
5
5
  var impressionsTracker_1 = require("../trackers/impressionsTracker");
6
6
  var eventTracker_1 = require("../trackers/eventTracker");
7
7
  var telemetryTracker_1 = require("../trackers/telemetryTracker");
8
- var key_1 = require("../utils/key");
9
- var utils_1 = require("../trackers/impressionObserver/utils");
10
8
  var apiKey_1 = require("../utils/inputValidation/apiKey");
11
9
  var sdkLogger_1 = require("../logger/sdkLogger");
12
10
  var constants_1 = require("../logger/constants");
13
- var metadataBuilder_1 = require("../storages/metadataBuilder");
14
11
  var constants_2 = require("../readiness/constants");
15
12
  var objectAssign_1 = require("../utils/lang/objectAssign");
13
+ var strategyDebug_1 = require("../trackers/strategy/strategyDebug");
14
+ var strategyOptimized_1 = require("../trackers/strategy/strategyOptimized");
15
+ var strategyNone_1 = require("../trackers/strategy/strategyNone");
16
+ var uniqueKeysTracker_1 = require("../trackers/uniqueKeysTracker");
17
+ var constants_3 = require("../utils/constants");
16
18
  /**
17
19
  * Modular SDK factory
18
20
  */
19
21
  function sdkFactory(params) {
20
- 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;
21
- var log = settings.log;
22
+ 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, impressionsMode = settings.sync.impressionsMode;
22
24
  // @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid API Key, etc.
23
25
  // On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
24
26
  // We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
25
27
  (0, apiKey_1.validateAndTrackApiKey)(log, settings.core.authorizationKey);
26
28
  var sdkReadinessManager = (0, sdkReadinessManager_1.sdkReadinessManagerFactory)(log, platform.EventEmitter, settings.startup.readyTimeout);
27
29
  var readiness = sdkReadinessManager.readinessManager;
28
- // @TODO consider passing the settings object, so that each storage access only what it needs
29
- var storageFactoryParams = {
30
- impressionsQueueSize: settings.scheduler.impressionsQueueSize,
31
- eventsQueueSize: settings.scheduler.eventsQueueSize,
32
- optimize: (0, utils_1.shouldBeOptimized)(settings),
33
- // ATM, only used by InLocalStorage
34
- matchingKey: (0, key_1.getMatching)(settings.core.key),
35
- splitFiltersValidation: settings.sync.__splitFiltersValidation,
36
- // ATM, only used by PluggableStorage
37
- mode: settings.mode,
38
- // Callback used to emit SDK_READY in consumer mode, where `syncManagerFactory` is undefined,
39
- // or partial consumer mode, where it only has submitters, and therefore it doesn't emit readiness events.
30
+ var storage = storageFactory({
31
+ settings: settings,
40
32
  onReadyCb: function (error) {
41
33
  if (error)
42
34
  return; // Don't emit SDK_READY if storage failed to connect. Error message is logged by wrapperAdapter
43
35
  readiness.splits.emit(constants_2.SDK_SPLITS_ARRIVED);
44
36
  readiness.segments.emit(constants_2.SDK_SEGMENTS_ARRIVED);
45
37
  },
46
- metadata: (0, metadataBuilder_1.metadataBuilder)(settings),
47
- log: log
48
- };
49
- var storage = storageFactory(storageFactoryParams);
38
+ });
50
39
  // @TODO add support for dataloader: `if (params.dataLoader) params.dataLoader(storage);`
51
40
  var telemetryTracker = (0, telemetryTracker_1.telemetryTrackerFactory)(storage.telemetry, platform.now);
52
41
  var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
53
- // trackers
54
- var observer = impressionsObserverFactory && impressionsObserverFactory();
55
- var impressionsTracker = (0, impressionsTracker_1.impressionsTrackerFactory)(settings, storage.impressions, integrationsManager, observer, storage.impressionCounts, storage.telemetry);
42
+ var observer = impressionsObserverFactory();
43
+ var uniqueKeysTracker = impressionsMode === constants_3.NONE ? (0, uniqueKeysTracker_1.uniqueKeysTrackerFactory)(log, storage.uniqueKeys, filterAdapterFactory && filterAdapterFactory()) : undefined;
44
+ var strategy;
45
+ switch (impressionsMode) {
46
+ case constants_3.OPTIMIZED:
47
+ strategy = (0, strategyOptimized_1.strategyOptimizedFactory)(observer, storage.impressionCounts);
48
+ break;
49
+ case constants_3.NONE:
50
+ strategy = (0, strategyNone_1.strategyNoneFactory)(storage.impressionCounts, uniqueKeysTracker);
51
+ break;
52
+ default:
53
+ strategy = (0, strategyDebug_1.strategyDebugFactory)(observer);
54
+ }
55
+ var impressionsTracker = (0, impressionsTracker_1.impressionsTrackerFactory)(settings, storage.impressions, strategy, integrationsManager, storage.telemetry);
56
56
  var eventTracker = (0, eventTracker_1.eventTrackerFactory)(settings, storage.events, integrationsManager, storage.telemetry);
57
57
  // splitApi is used by SyncManager and Browser signal listener
58
58
  var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
59
- var ctx = { splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform };
59
+ var ctx = { splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, uniqueKeysTracker: uniqueKeysTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform };
60
60
  var syncManager = syncManagerFactory && syncManagerFactory(ctx);
61
61
  ctx.syncManager = syncManager;
62
62
  var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
@@ -77,7 +77,7 @@ function sdkFactory(params) {
77
77
  return managerInstance;
78
78
  },
79
79
  // Logger wrapper API
80
- Logger: (0, sdkLogger_1.createLoggerAPI)(settings.log),
80
+ Logger: (0, sdkLogger_1.createLoggerAPI)(log),
81
81
  settings: settings,
82
82
  }, extraProps && extraProps(ctx));
83
83
  }
@@ -90,6 +90,26 @@ function splitApiFactory(settings, platform, telemetryTracker) {
90
90
  var url = urls.events + "/testImpressions/count";
91
91
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.IMPRESSIONS_COUNT));
92
92
  },
93
+ /**
94
+ * Post unique keys for client side.
95
+ *
96
+ * @param body unique keys payload
97
+ * @param headers Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
98
+ */
99
+ postUniqueKeysBulkCs: function (body, headers) {
100
+ var url = urls.telemetry + "/v1/keys/cs";
101
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.TELEMETRY));
102
+ },
103
+ /**
104
+ * Post unique keys for server side.
105
+ *
106
+ * @param body unique keys payload
107
+ * @param headers Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
108
+ */
109
+ postUniqueKeysBulkSs: function (body, headers) {
110
+ var url = urls.telemetry + "/v1/keys/ss";
111
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.TELEMETRY));
112
+ },
93
113
  postMetricsConfig: function (body, headers) {
94
114
  var url = urls.telemetry + "/v1/metrics/config";
95
115
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.TELEMETRY), true);
@@ -28,7 +28,7 @@ var AbstractSplitsCacheAsync = /** @class */ (function () {
28
28
  * @param {string} name
29
29
  * @param {string} defaultTreatment
30
30
  * @param {number} changeNumber
31
- * @returns {Promise} a promise that is resolved once the split kill operation is performed. The fulfillment value is a boolean: `true` if the kill success updating the split or `false` if no split is updated,
31
+ * @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,
32
32
  * 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.
33
33
  * The promise will never be rejected.
34
34
  */
@@ -43,7 +43,7 @@ var AbstractSplitsCacheSync = /** @class */ (function () {
43
43
  * @param {string} name
44
44
  * @param {string} defaultTreatment
45
45
  * @param {number} changeNumber
46
- * @returns {Promise} a promise that is resolved once the split kill is performed. The fulfillment value is a boolean: `true` if the kill success updating the split or `false` if no split is updated,
46
+ * @returns {boolean} `true` if the operation successed updating the split, or `false` if no split is updated,
47
47
  * 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.
48
48
  */
49
49
  AbstractSplitsCacheSync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseLatencyField = exports.parseExceptionField = exports.parseMetadata = exports.KeyBuilderSS = void 0;
3
+ exports.KeyBuilderSS = exports.METHOD_NAMES = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var KeyBuilder_1 = require("./KeyBuilder");
6
- var TelemetryCacheInMemory_1 = require("./inMemory/TelemetryCacheInMemory");
7
- var METHOD_NAMES = {
6
+ exports.METHOD_NAMES = {
8
7
  t: 'treatment',
9
8
  ts: 'treatments',
10
9
  tc: 'treatmentWithConfig',
@@ -27,6 +26,12 @@ var KeyBuilderSS = /** @class */ (function (_super) {
27
26
  KeyBuilderSS.prototype.buildImpressionsKey = function () {
28
27
  return this.prefix + ".impressions";
29
28
  };
29
+ KeyBuilderSS.prototype.buildImpressionsCountKey = function () {
30
+ return this.prefix + ".impressions.count";
31
+ };
32
+ KeyBuilderSS.prototype.buildUniqueKeysKey = function () {
33
+ return this.prefix + ".uniquekeys";
34
+ };
30
35
  KeyBuilderSS.prototype.buildEventsKey = function () {
31
36
  return this.prefix + ".events";
32
37
  };
@@ -35,10 +40,10 @@ var KeyBuilderSS = /** @class */ (function (_super) {
35
40
  };
36
41
  /* Telemetry keys */
37
42
  KeyBuilderSS.prototype.buildLatencyKey = function (method, bucket) {
38
- return this.latencyPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method] + "/" + bucket;
43
+ return this.latencyPrefix + "::" + this.versionablePrefix + "/" + exports.METHOD_NAMES[method] + "/" + bucket;
39
44
  };
40
45
  KeyBuilderSS.prototype.buildExceptionKey = function (method) {
41
- return this.exceptionPrefix + "::" + this.versionablePrefix + "/" + METHOD_NAMES[method];
46
+ return this.exceptionPrefix + "::" + this.versionablePrefix + "/" + exports.METHOD_NAMES[method];
42
47
  };
43
48
  KeyBuilderSS.prototype.buildInitKey = function () {
44
49
  return this.initPrefix + "::" + this.versionablePrefix;
@@ -46,41 +51,3 @@ var KeyBuilderSS = /** @class */ (function (_super) {
46
51
  return KeyBuilderSS;
47
52
  }(KeyBuilder_1.KeyBuilder));
48
53
  exports.KeyBuilderSS = KeyBuilderSS;
49
- // Used by consumer methods of TelemetryCacheInRedis and TelemetryCachePluggable
50
- var REVERSE_METHOD_NAMES = Object.keys(METHOD_NAMES).reduce(function (acc, key) {
51
- acc[METHOD_NAMES[key]] = key;
52
- return acc;
53
- }, {});
54
- function parseMetadata(field) {
55
- var parts = field.split('/');
56
- if (parts.length !== 3)
57
- return "invalid subsection count. Expected 4, got: " + parts.length;
58
- var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */;
59
- return [JSON.stringify({ s: s, n: n, i: i })];
60
- }
61
- exports.parseMetadata = parseMetadata;
62
- function parseExceptionField(field) {
63
- var parts = field.split('/');
64
- if (parts.length !== 4)
65
- return "invalid subsection count. Expected 4, got: " + parts.length;
66
- var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3];
67
- var method = REVERSE_METHOD_NAMES[m];
68
- if (!method)
69
- return "unknown method '" + m + "'";
70
- return [JSON.stringify({ s: s, n: n, i: i }), method];
71
- }
72
- exports.parseExceptionField = parseExceptionField;
73
- function parseLatencyField(field) {
74
- var parts = field.split('/');
75
- if (parts.length !== 5)
76
- return "invalid subsection count. Expected 5, got: " + parts.length;
77
- var s = parts[0] /* metadata.s */, n = parts[1] /* metadata.n */, i = parts[2] /* metadata.i */, m = parts[3], b = parts[4];
78
- var method = REVERSE_METHOD_NAMES[m];
79
- if (!method)
80
- return "unknown method '" + m + "'";
81
- var bucket = parseInt(b);
82
- if (isNaN(bucket) || bucket >= TelemetryCacheInMemory_1.MAX_LATENCY_BUCKET_COUNT)
83
- return "invalid bucket. Expected a number between 0 and 22, got: " + b;
84
- return [JSON.stringify({ s: s, n: n, i: i }), method, bucket];
85
- }
86
- exports.parseLatencyField = parseLatencyField;
@@ -203,7 +203,6 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
203
203
  };
204
204
  /**
205
205
  * Clean Splits cache if its `lastUpdated` timestamp is older than the given `expirationTimestamp`,
206
- * Clean operation (clear) also updates `lastUpdated` timestamp with current time.
207
206
  *
208
207
  * @param {number | undefined} expirationTimestamp if the value is not a number, data will not be cleaned
209
208
  */
@@ -16,6 +16,8 @@ var InMemoryStorageCS_1 = require("../inMemory/InMemoryStorageCS");
16
16
  var constants_1 = require("./constants");
17
17
  var constants_2 = require("../../utils/constants");
18
18
  var TelemetryCacheInMemory_1 = require("../inMemory/TelemetryCacheInMemory");
19
+ var UniqueKeysCacheInMemoryCS_1 = require("../inMemory/UniqueKeysCacheInMemoryCS");
20
+ var key_1 = require("../../utils/key");
19
21
  /**
20
22
  * InLocal storage factory for standalone client-side SplitFactory
21
23
  */
@@ -25,25 +27,31 @@ function InLocalStorage(options) {
25
27
  function InLocalStorageCSFactory(params) {
26
28
  // Fallback to InMemoryStorage if LocalStorage API is not available
27
29
  if (!(0, isLocalStorageAvailable_1.isLocalStorageAvailable)()) {
28
- params.log.warn(constants_1.LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
30
+ params.settings.log.warn(constants_1.LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
29
31
  return (0, InMemoryStorageCS_1.InMemoryStorageCSFactory)(params);
30
32
  }
31
- var log = params.log;
32
- var keys = new KeyBuilderCS_1.KeyBuilderCS(prefix, params.matchingKey);
33
+ 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;
34
+ var matchingKey = (0, key_1.getMatching)(settings.core.key);
35
+ var keys = new KeyBuilderCS_1.KeyBuilderCS(prefix, matchingKey);
33
36
  var expirationTimestamp = Date.now() - browser_1.DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
37
+ var splits = new SplitsCacheInLocal_1.SplitsCacheInLocal(log, keys, expirationTimestamp, __splitFiltersValidation);
38
+ var segments = new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, keys);
34
39
  return {
35
- splits: new SplitsCacheInLocal_1.SplitsCacheInLocal(log, keys, expirationTimestamp, params.splitFiltersValidation),
36
- segments: new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, keys),
37
- impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(params.impressionsQueueSize),
38
- impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
39
- events: new EventsCacheInMemory_1.EventsCacheInMemory(params.eventsQueueSize),
40
- telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory() : undefined,
40
+ splits: splits,
41
+ segments: segments,
42
+ impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize),
43
+ impressionCounts: impressionsMode !== constants_2.DEBUG ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
44
+ events: new EventsCacheInMemory_1.EventsCacheInMemory(eventsQueueSize),
45
+ telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory(splits, segments) : undefined,
46
+ uniqueKeys: impressionsMode === constants_2.NONE ? new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() : undefined,
41
47
  destroy: function () {
48
+ var _a;
42
49
  this.splits = new SplitsCacheInMemory_1.SplitsCacheInMemory();
43
50
  this.segments = new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory();
44
51
  this.impressions.clear();
45
52
  this.impressionCounts && this.impressionCounts.clear();
46
53
  this.events.clear();
54
+ (_a = this.uniqueKeys) === null || _a === void 0 ? void 0 : _a.clear();
47
55
  },
48
56
  // When using shared instanciation with MEMORY we reuse everything but segments (they are customer per key).
49
57
  shared: function (matchingKey) {
@@ -2,9 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ImpressionCountsCacheInMemory = void 0;
4
4
  var time_1 = require("../../utils/time");
5
+ var constants_1 = require("../inRedis/constants");
5
6
  var ImpressionCountsCacheInMemory = /** @class */ (function () {
6
- function ImpressionCountsCacheInMemory() {
7
+ function ImpressionCountsCacheInMemory(impressionCountsCacheSize) {
8
+ if (impressionCountsCacheSize === void 0) { impressionCountsCacheSize = constants_1.DEFAULT_CACHE_SIZE; }
7
9
  this.cache = {};
10
+ this.cacheSize = 0;
11
+ this.maxStorage = impressionCountsCacheSize;
8
12
  }
9
13
  /**
10
14
  * Builds key to be stored in the cache with the featureName and the timeFrame truncated.
@@ -19,6 +23,13 @@ var ImpressionCountsCacheInMemory = /** @class */ (function () {
19
23
  var key = this._makeKey(featureName, timeFrame);
20
24
  var currentAmount = this.cache[key];
21
25
  this.cache[key] = currentAmount ? currentAmount + amount : amount;
26
+ if (this.onFullQueue) {
27
+ this.cacheSize = this.cacheSize + amount;
28
+ if (this.cacheSize >= this.maxStorage) {
29
+ this.onFullQueue();
30
+ this.cacheSize = 0;
31
+ }
32
+ }
22
33
  };
23
34
  /**
24
35
  * Pop the collected data, used as payload for posting.
@@ -8,26 +8,33 @@ var EventsCacheInMemory_1 = require("./EventsCacheInMemory");
8
8
  var ImpressionCountsCacheInMemory_1 = require("./ImpressionCountsCacheInMemory");
9
9
  var constants_1 = require("../../utils/constants");
10
10
  var TelemetryCacheInMemory_1 = require("./TelemetryCacheInMemory");
11
+ var UniqueKeysCacheInMemory_1 = require("./UniqueKeysCacheInMemory");
11
12
  /**
12
13
  * InMemory storage factory for standalone server-side SplitFactory
13
14
  *
14
15
  * @param params parameters required by EventsCacheSync
15
16
  */
16
17
  function InMemoryStorageFactory(params) {
18
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
19
+ var splits = new SplitsCacheInMemory_1.SplitsCacheInMemory();
20
+ var segments = new SegmentsCacheInMemory_1.SegmentsCacheInMemory();
17
21
  return {
18
- splits: new SplitsCacheInMemory_1.SplitsCacheInMemory(),
19
- segments: new SegmentsCacheInMemory_1.SegmentsCacheInMemory(),
20
- impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(params.impressionsQueueSize),
21
- impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
22
- events: new EventsCacheInMemory_1.EventsCacheInMemory(params.eventsQueueSize),
23
- telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory() : undefined,
22
+ splits: splits,
23
+ segments: segments,
24
+ impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize),
25
+ impressionCounts: impressionsMode !== constants_1.DEBUG ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
26
+ events: new EventsCacheInMemory_1.EventsCacheInMemory(eventsQueueSize),
27
+ telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory(splits, segments) : undefined,
28
+ uniqueKeys: impressionsMode === constants_1.NONE ? new UniqueKeysCacheInMemory_1.UniqueKeysCacheInMemory() : undefined,
24
29
  // When using MEMORY we should clean all the caches to leave them empty
25
30
  destroy: function () {
31
+ var _a;
26
32
  this.splits.clear();
27
33
  this.segments.clear();
28
34
  this.impressions.clear();
29
35
  this.impressionCounts && this.impressionCounts.clear();
30
36
  this.events.clear();
37
+ (_a = this.uniqueKeys) === null || _a === void 0 ? void 0 : _a.clear();
31
38
  }
32
39
  };
33
40
  }
@@ -8,26 +8,33 @@ var EventsCacheInMemory_1 = require("./EventsCacheInMemory");
8
8
  var ImpressionCountsCacheInMemory_1 = require("./ImpressionCountsCacheInMemory");
9
9
  var constants_1 = require("../../utils/constants");
10
10
  var TelemetryCacheInMemory_1 = require("./TelemetryCacheInMemory");
11
+ var UniqueKeysCacheInMemoryCS_1 = require("./UniqueKeysCacheInMemoryCS");
11
12
  /**
12
13
  * InMemory storage factory for standalone client-side SplitFactory
13
14
  *
14
15
  * @param params parameters required by EventsCacheSync
15
16
  */
16
17
  function InMemoryStorageCSFactory(params) {
18
+ var _a = params.settings, _b = _a.scheduler, impressionsQueueSize = _b.impressionsQueueSize, eventsQueueSize = _b.eventsQueueSize, impressionsMode = _a.sync.impressionsMode;
19
+ var splits = new SplitsCacheInMemory_1.SplitsCacheInMemory();
20
+ var segments = new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory();
17
21
  return {
18
- splits: new SplitsCacheInMemory_1.SplitsCacheInMemory(),
19
- segments: new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory(),
20
- impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(params.impressionsQueueSize),
21
- impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
22
- events: new EventsCacheInMemory_1.EventsCacheInMemory(params.eventsQueueSize),
23
- telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory() : undefined,
22
+ splits: splits,
23
+ segments: segments,
24
+ impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize),
25
+ impressionCounts: impressionsMode !== constants_1.DEBUG ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
26
+ events: new EventsCacheInMemory_1.EventsCacheInMemory(eventsQueueSize),
27
+ telemetry: (0, TelemetryCacheInMemory_1.shouldRecordTelemetry)(params) ? new TelemetryCacheInMemory_1.TelemetryCacheInMemory(splits, segments) : undefined,
28
+ uniqueKeys: impressionsMode === constants_1.NONE ? new UniqueKeysCacheInMemoryCS_1.UniqueKeysCacheInMemoryCS() : undefined,
24
29
  // When using MEMORY we should clean all the caches to leave them empty
25
30
  destroy: function () {
31
+ var _a;
26
32
  this.splits.clear();
27
33
  this.segments.clear();
28
34
  this.impressions.clear();
29
35
  this.impressionCounts && this.impressionCounts.clear();
30
36
  this.events.clear();
37
+ (_a = this.uniqueKeys) === null || _a === void 0 ? void 0 : _a.clear();
31
38
  },
32
39
  // When using shared instanciation with MEMORY we reuse everything but segments (they are unique per key)
33
40
  shared: function () {