@splitsoftware/splitio-commons 1.3.1 → 1.3.2-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 (219) hide show
  1. package/cjs/consent/sdkUserConsent.js +1 -1
  2. package/cjs/listeners/browser.js +5 -4
  3. package/cjs/logger/constants.js +2 -1
  4. package/cjs/logger/messages/error.js +2 -1
  5. package/cjs/logger/messages/info.js +3 -3
  6. package/cjs/logger/messages/warn.js +2 -2
  7. package/cjs/sdkClient/client.js +17 -3
  8. package/cjs/sdkClient/sdkClient.js +4 -1
  9. package/cjs/sdkFactory/index.js +16 -19
  10. package/cjs/services/splitApi.js +15 -14
  11. package/cjs/services/splitHttpClient.js +4 -1
  12. package/cjs/storages/AbstractSegmentsCacheSync.js +0 -5
  13. package/cjs/storages/KeyBuilderSS.js +12 -19
  14. package/cjs/storages/findLatencyIndex.js +11 -6
  15. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +13 -1
  16. package/cjs/storages/inLocalStorage/index.js +4 -1
  17. package/cjs/storages/inMemory/InMemoryStorage.js +2 -0
  18. package/cjs/storages/inMemory/InMemoryStorageCS.js +3 -0
  19. package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +6 -0
  20. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +6 -0
  21. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +165 -0
  22. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +29 -0
  23. package/cjs/storages/inRedis/index.js +2 -4
  24. package/cjs/storages/pluggable/TelemetryCachePluggable.js +27 -0
  25. package/cjs/storages/pluggable/index.js +2 -1
  26. package/cjs/sync/polling/pollingManagerCS.js +1 -1
  27. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +2 -2
  28. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +0 -3
  29. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -8
  30. package/cjs/sync/polling/updaters/splitChangesUpdater.js +3 -6
  31. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +20 -13
  32. package/cjs/sync/streaming/SSEHandler/index.js +21 -15
  33. package/cjs/sync/streaming/pushManager.js +7 -4
  34. package/cjs/sync/submitters/eventsSubmitter.js +28 -0
  35. package/cjs/sync/submitters/{impressionCountsSyncTask.js → impressionCountsSubmitter.js} +10 -7
  36. package/cjs/sync/submitters/{impressionsSyncTask.js → impressionsSubmitter.js} +8 -8
  37. package/cjs/sync/submitters/submitter.js +66 -0
  38. package/cjs/sync/submitters/submitterManager.js +12 -10
  39. package/cjs/sync/submitters/telemetrySubmitter.js +128 -0
  40. package/cjs/sync/syncManagerOnline.js +6 -2
  41. package/cjs/trackers/eventTracker.js +5 -1
  42. package/cjs/trackers/impressionsTracker.js +9 -1
  43. package/cjs/trackers/telemetryTracker.js +65 -0
  44. package/cjs/utils/constants/index.js +40 -1
  45. package/cjs/utils/inputValidation/apiKey.js +12 -11
  46. package/cjs/utils/settingsValidation/index.js +35 -11
  47. package/cjs/utils/settingsValidation/url.js +4 -0
  48. package/cjs/utils/timeTracker/index.js +1 -0
  49. package/cjs/utils/timeTracker/timer.js +2 -2
  50. package/esm/consent/sdkUserConsent.js +1 -1
  51. package/esm/listeners/browser.js +3 -2
  52. package/esm/logger/constants.js +1 -0
  53. package/esm/logger/messages/error.js +2 -1
  54. package/esm/logger/messages/info.js +3 -3
  55. package/esm/logger/messages/warn.js +2 -2
  56. package/esm/sdkClient/client.js +18 -4
  57. package/esm/sdkClient/sdkClient.js +4 -1
  58. package/esm/sdkFactory/index.js +16 -19
  59. package/esm/services/splitApi.js +15 -14
  60. package/esm/services/splitHttpClient.js +4 -1
  61. package/esm/storages/AbstractSegmentsCacheSync.js +0 -5
  62. package/esm/storages/KeyBuilderSS.js +12 -19
  63. package/esm/storages/findLatencyIndex.js +11 -6
  64. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +13 -1
  65. package/esm/storages/inLocalStorage/index.js +5 -2
  66. package/esm/storages/inMemory/InMemoryStorage.js +3 -1
  67. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -1
  68. package/esm/storages/inMemory/MySegmentsCacheInMemory.js +6 -0
  69. package/esm/storages/inMemory/SegmentsCacheInMemory.js +6 -0
  70. package/esm/storages/inMemory/TelemetryCacheInMemory.js +161 -0
  71. package/esm/storages/inRedis/TelemetryCacheInRedis.js +26 -0
  72. package/esm/storages/inRedis/index.js +2 -4
  73. package/esm/storages/pluggable/TelemetryCachePluggable.js +24 -0
  74. package/esm/storages/pluggable/index.js +2 -1
  75. package/esm/sync/polling/pollingManagerCS.js +1 -1
  76. package/esm/sync/polling/syncTasks/splitsSyncTask.js +2 -2
  77. package/esm/sync/polling/updaters/mySegmentsUpdater.js +0 -3
  78. package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -8
  79. package/esm/sync/polling/updaters/splitChangesUpdater.js +3 -6
  80. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +8 -1
  81. package/esm/sync/streaming/SSEHandler/index.js +21 -15
  82. package/esm/sync/streaming/pushManager.js +7 -4
  83. package/esm/sync/submitters/eventsSubmitter.js +24 -0
  84. package/esm/sync/submitters/{impressionCountsSyncTask.js → impressionCountsSubmitter.js} +8 -5
  85. package/esm/sync/submitters/{impressionsSyncTask.js → impressionsSubmitter.js} +6 -6
  86. package/esm/sync/submitters/submitter.js +61 -0
  87. package/esm/sync/submitters/submitterManager.js +12 -10
  88. package/esm/sync/submitters/telemetrySubmitter.js +122 -0
  89. package/esm/sync/syncManagerOnline.js +6 -2
  90. package/esm/trackers/eventTracker.js +6 -2
  91. package/esm/trackers/impressionsTracker.js +10 -2
  92. package/esm/trackers/telemetryTracker.js +61 -0
  93. package/esm/utils/constants/index.js +38 -0
  94. package/esm/utils/inputValidation/apiKey.js +2 -1
  95. package/esm/utils/settingsValidation/index.js +34 -10
  96. package/esm/utils/settingsValidation/url.js +4 -0
  97. package/esm/utils/timeTracker/index.js +1 -0
  98. package/esm/utils/timeTracker/timer.js +2 -2
  99. package/package.json +1 -1
  100. package/src/consent/sdkUserConsent.ts +1 -1
  101. package/src/listeners/browser.ts +3 -2
  102. package/src/logger/constants.ts +1 -0
  103. package/src/logger/messages/error.ts +2 -1
  104. package/src/logger/messages/info.ts +3 -3
  105. package/src/logger/messages/warn.ts +2 -2
  106. package/src/sdkClient/client.ts +23 -4
  107. package/src/sdkClient/sdkClient.ts +4 -1
  108. package/src/sdkFactory/index.ts +22 -24
  109. package/src/sdkFactory/types.ts +32 -15
  110. package/src/services/splitApi.ts +17 -14
  111. package/src/services/splitHttpClient.ts +6 -3
  112. package/src/services/types.ts +7 -5
  113. package/src/storages/AbstractSegmentsCacheSync.ts +8 -3
  114. package/src/storages/KeyBuilderSS.ts +13 -50
  115. package/src/storages/findLatencyIndex.ts +12 -3
  116. package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +13 -1
  117. package/src/storages/inLocalStorage/index.ts +5 -2
  118. package/src/storages/inMemory/InMemoryStorage.ts +3 -1
  119. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -1
  120. package/src/storages/inMemory/MySegmentsCacheInMemory.ts +8 -0
  121. package/src/storages/inMemory/SegmentsCacheInMemory.ts +6 -0
  122. package/src/storages/inMemory/TelemetryCacheInMemory.ts +210 -0
  123. package/src/storages/inRedis/TelemetryCacheInRedis.ts +29 -0
  124. package/src/storages/inRedis/index.ts +2 -4
  125. package/src/storages/pluggable/TelemetryCachePluggable.ts +26 -0
  126. package/src/storages/pluggable/index.ts +2 -1
  127. package/src/storages/types.ts +84 -32
  128. package/src/sync/offline/syncManagerOffline.ts +4 -3
  129. package/src/sync/polling/pollingManagerCS.ts +3 -3
  130. package/src/sync/polling/pollingManagerSS.ts +2 -2
  131. package/src/sync/polling/syncTasks/splitsSyncTask.ts +2 -0
  132. package/src/sync/polling/updaters/mySegmentsUpdater.ts +0 -4
  133. package/src/sync/polling/updaters/segmentChangesUpdater.ts +2 -10
  134. package/src/sync/polling/updaters/splitChangesUpdater.ts +3 -6
  135. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +11 -1
  136. package/src/sync/streaming/SSEHandler/index.ts +21 -14
  137. package/src/sync/streaming/pushManager.ts +11 -7
  138. package/src/sync/submitters/eventsSubmitter.ts +35 -0
  139. package/src/sync/submitters/{impressionCountsSyncTask.ts → impressionCountsSubmitter.ts} +15 -15
  140. package/src/sync/submitters/{impressionsSyncTask.ts → impressionsSubmitter.ts} +12 -16
  141. package/src/sync/submitters/{submitterSyncTask.ts → submitter.ts} +34 -16
  142. package/src/sync/submitters/submitterManager.ts +14 -11
  143. package/src/sync/submitters/telemetrySubmitter.ts +143 -0
  144. package/src/sync/submitters/types.ts +123 -0
  145. package/src/sync/syncManagerOnline.ts +13 -7
  146. package/src/sync/types.ts +0 -15
  147. package/src/trackers/eventTracker.ts +7 -3
  148. package/src/trackers/impressionsTracker.ts +11 -3
  149. package/src/trackers/telemetryTracker.ts +63 -0
  150. package/src/trackers/types.ts +24 -0
  151. package/src/types.ts +35 -6
  152. package/src/utils/constants/index.ts +45 -0
  153. package/src/utils/inputValidation/apiKey.ts +2 -1
  154. package/src/utils/settingsValidation/index.ts +35 -11
  155. package/src/utils/settingsValidation/url.ts +4 -0
  156. package/src/utils/timeTracker/index.ts +1 -1
  157. package/src/utils/timeTracker/timer.ts +3 -3
  158. package/types/logger/constants.d.ts +1 -0
  159. package/types/sdkFactory/types.d.ts +29 -14
  160. package/types/services/splitApi.d.ts +2 -1
  161. package/types/services/types.d.ts +8 -5
  162. package/types/storages/AbstractSegmentsCacheSync.d.ts +7 -3
  163. package/types/storages/KeyBuilderSS.d.ts +3 -3
  164. package/types/storages/findLatencyIndex.d.ts +7 -1
  165. package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +2 -0
  166. package/types/storages/inMemory/MySegmentsCacheInMemory.d.ts +2 -0
  167. package/types/storages/inMemory/SegmentsCacheInMemory.d.ts +1 -0
  168. package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -2
  169. package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +3 -3
  170. package/types/storages/pluggable/TelemetryCachePluggable.d.ts +2 -2
  171. package/types/storages/types.d.ts +71 -22
  172. package/types/sync/offline/syncManagerOffline.d.ts +3 -2
  173. package/types/sync/polling/pollingManagerCS.d.ts +2 -2
  174. package/types/sync/polling/pollingManagerSS.d.ts +2 -2
  175. package/types/sync/polling/syncTasks/splitsSyncTask.d.ts +1 -1
  176. package/types/sync/polling/updaters/splitChangesUpdater.d.ts +1 -1
  177. package/types/sync/streaming/SSEHandler/NotificationKeeper.d.ts +2 -1
  178. package/types/sync/streaming/SSEHandler/index.d.ts +2 -1
  179. package/types/sync/streaming/pushManager.d.ts +2 -2
  180. package/types/sync/submitters/eventsSubmitter.d.ts +5 -0
  181. package/types/sync/submitters/impressionCountsSubmitter.d.ts +10 -0
  182. package/types/sync/submitters/impressionsSubmitter.d.ts +11 -0
  183. package/types/sync/submitters/submitter.d.ts +12 -0
  184. package/types/sync/submitters/submitterManager.d.ts +2 -2
  185. package/types/sync/submitters/telemetrySubmitter.d.ts +24 -0
  186. package/types/sync/submitters/telemetrySyncTask.d.ts +0 -27
  187. package/types/sync/submitters/types.d.ts +107 -0
  188. package/types/sync/syncManagerOnline.d.ts +3 -2
  189. package/types/sync/types.d.ts +0 -13
  190. package/types/trackers/eventTracker.d.ts +2 -2
  191. package/types/trackers/impressionsTracker.d.ts +2 -2
  192. package/types/trackers/telemetryTracker.d.ts +2 -3
  193. package/types/trackers/types.d.ts +22 -0
  194. package/types/types.d.ts +33 -4
  195. package/types/utils/constants/index.d.ts +37 -0
  196. package/types/utils/inputValidation/apiKey.d.ts +1 -0
  197. package/types/utils/settingsValidation/index.d.ts +40 -0
  198. package/types/utils/timeTracker/index.d.ts +1 -1
  199. package/types/utils/timeTracker/timer.d.ts +1 -1
  200. package/cjs/storages/inMemory/CountsCacheInMemory.js +0 -38
  201. package/cjs/storages/inMemory/LatenciesCacheInMemory.js +0 -43
  202. package/cjs/storages/inRedis/CountsCacheInRedis.js +0 -16
  203. package/cjs/storages/inRedis/LatenciesCacheInRedis.js +0 -18
  204. package/cjs/sync/submitters/eventsSyncTask.js +0 -44
  205. package/cjs/sync/submitters/metricsSyncTask.js +0 -31
  206. package/cjs/sync/submitters/submitterSyncTask.js +0 -44
  207. package/esm/storages/inMemory/CountsCacheInMemory.js +0 -35
  208. package/esm/storages/inMemory/LatenciesCacheInMemory.js +0 -40
  209. package/esm/storages/inRedis/CountsCacheInRedis.js +0 -13
  210. package/esm/storages/inRedis/LatenciesCacheInRedis.js +0 -15
  211. package/esm/sync/submitters/eventsSyncTask.js +0 -40
  212. package/esm/sync/submitters/metricsSyncTask.js +0 -26
  213. package/esm/sync/submitters/submitterSyncTask.js +0 -40
  214. package/src/storages/inMemory/CountsCacheInMemory.ts +0 -37
  215. package/src/storages/inMemory/LatenciesCacheInMemory.ts +0 -45
  216. package/src/storages/inRedis/CountsCacheInRedis.ts +0 -20
  217. package/src/storages/inRedis/LatenciesCacheInRedis.ts +0 -23
  218. package/src/sync/submitters/eventsSyncTask.ts +0 -57
  219. package/src/sync/submitters/metricsSyncTask.ts +0 -49
@@ -31,5 +31,6 @@ export var codesError = [
31
31
  // initialization / settings validation
32
32
  [c.ERROR_INVALID_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "%s" config param. It should be one of the following values: %s. Defaulting to "%s".'],
33
33
  [c.ERROR_LOCALHOST_MODULE_REQUIRED, c.LOG_PREFIX_SETTINGS + ': an invalid value was received for "sync.localhostMode" config. A valid entity should be provided for localhost mode.'],
34
- [c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS + ': The provided storage is invalid.%s Fallbacking into default MEMORY storage'],
34
+ [c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS + ': the provided storage is invalid.%s Falling back into default MEMORY storage'],
35
+ [c.ERROR_MIN_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': the provided "%s" config param is lower than allowed. Setting to the minimum value %s seconds'],
35
36
  ];
@@ -12,8 +12,8 @@ export var codesInfo = codesWarn.concat([
12
12
  [c.NEW_FACTORY, 'New Split SDK instance created.'],
13
13
  [c.EVENTS_TRACKER_SUCCESS, c.LOG_PREFIX_EVENTS_TRACKER + 'Successfully queued %s'],
14
14
  [c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
15
- [c.USER_CONSENT_UPDATED, 'setUserConsent: consent status changed from %s to %s.'],
16
- [c.USER_CONSENT_NOT_UPDATED, 'setUserConsent: call had no effect because it was the current consent status (%s).'],
15
+ [c.USER_CONSENT_UPDATED, 'UserConsent: consent status changed from %s to %s.'],
16
+ [c.USER_CONSENT_NOT_UPDATED, 'UserConsent: call had no effect because it was the current consent status (%s).'],
17
17
  [c.USER_CONSENT_INITIAL, 'Starting the SDK with %s user consent. No data will be sent.'],
18
18
  // synchronizer
19
19
  [c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
@@ -21,7 +21,7 @@ export var codesInfo = codesWarn.concat([
21
21
  [c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
22
22
  [c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of splits #%s. Reason: %s'],
23
23
  [c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and reseting timer.'],
24
- [c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s %s.'],
24
+ [c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s.'],
25
25
  [c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
26
26
  [c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
27
27
  [c.STREAMING_CONNECTING, c.LOG_PREFIX_SYNC_STREAMING + 'Connecting streaming.'],
@@ -10,8 +10,8 @@ export var codesWarn = codesError.concat([
10
10
  [c.STREAMING_PARSING_ERROR_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE error notification: %s'],
11
11
  [c.STREAMING_PARSING_MESSAGE_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE message notification: %s'],
12
12
  [c.STREAMING_FALLBACK, c.LOG_PREFIX_SYNC_STREAMING + 'Falling back to polling mode. Reason: %s'],
13
- [c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Droping %s %s after retry. Reason: %s.'],
14
- [c.SUBMITTERS_PUSH_RETRY, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Failed to push %s %s, keeping data to retry on next iteration. Reason: %s.'],
13
+ [c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Droping %s after retry. Reason: %s.'],
14
+ [c.SUBMITTERS_PUSH_RETRY, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Failed to push %s, keeping data to retry on next iteration. Reason: %s.'],
15
15
  // client status
16
16
  [c.CLIENT_NOT_READY, '%s: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method.'],
17
17
  [c.CLIENT_NO_LISTENER, 'No listeners for SDK Readiness detected. Incorrect control treatments could have been logged if you called getTreatment/s while the SDK was not yet ready.'],
@@ -4,21 +4,22 @@ import { getMatching, getBucketing } from '../utils/key';
4
4
  import { validateSplitExistance } from '../utils/inputValidation/splitExistance';
5
5
  import { validateTrafficTypeExistance } from '../utils/inputValidation/trafficTypeExistance';
6
6
  import { SDK_NOT_READY } from '../utils/labels';
7
- import { CONTROL } from '../utils/constants';
7
+ import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TRACK } from '../utils/constants';
8
8
  import { IMPRESSION, IMPRESSION_QUEUEING } from '../logger/constants';
9
9
  /**
10
10
  * Creator of base client with getTreatments and track methods.
11
11
  */
12
- // @TODO missing time tracking to collect telemetry
13
12
  export function clientFactory(params) {
14
- var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage, settings = params.settings, impressionsTracker = params.impressionsTracker, eventTracker = params.eventTracker;
13
+ var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage, settings = params.settings, impressionsTracker = params.impressionsTracker, eventTracker = params.eventTracker, telemetryTracker = params.telemetryTracker;
15
14
  var log = settings.log, mode = settings.mode;
16
15
  function getTreatment(key, splitName, attributes, withConfig) {
17
16
  if (withConfig === void 0) { withConfig = false; }
17
+ var stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? TREATMENT_WITH_CONFIG : TREATMENT);
18
18
  var wrapUp = function (evaluationResult) {
19
19
  var queue = [];
20
20
  var treatment = processEvaluation(evaluationResult, splitName, key, attributes, withConfig, "getTreatment" + (withConfig ? 'withConfig' : ''), queue);
21
21
  impressionsTracker.track(queue, attributes);
22
+ stopTelemetryTracker(queue[0] && queue[0].label);
22
23
  return treatment;
23
24
  };
24
25
  var evaluation = evaluateFeature(log, key, splitName, attributes, storage);
@@ -29,6 +30,7 @@ export function clientFactory(params) {
29
30
  }
30
31
  function getTreatments(key, splitNames, attributes, withConfig) {
31
32
  if (withConfig === void 0) { withConfig = false; }
33
+ var stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? TREATMENTS_WITH_CONFIG : TREATMENTS);
32
34
  var wrapUp = function (evaluationResults) {
33
35
  var queue = [];
34
36
  var treatments = {};
@@ -36,6 +38,7 @@ export function clientFactory(params) {
36
38
  treatments[splitName] = processEvaluation(evaluationResults[splitName], splitName, key, attributes, withConfig, "getTreatments" + (withConfig ? 'withConfig' : ''), queue);
37
39
  });
38
40
  impressionsTracker.track(queue, attributes);
41
+ stopTelemetryTracker(queue[0] && queue[0].label);
39
42
  return treatments;
40
43
  };
41
44
  var evaluations = evaluateFeatures(log, key, splitNames, attributes, storage);
@@ -77,6 +80,7 @@ export function clientFactory(params) {
77
80
  }
78
81
  function track(key, trafficTypeName, eventTypeId, value, properties, size) {
79
82
  if (size === void 0) { size = 1024; }
83
+ var stopTelemetryTracker = telemetryTracker.trackEval(TRACK);
80
84
  var matchingKey = getMatching(key);
81
85
  var timestamp = Date.now();
82
86
  var eventData = {
@@ -89,7 +93,17 @@ export function clientFactory(params) {
89
93
  };
90
94
  // This may be async but we only warn, we don't actually care if it is valid or not in terms of queueing the event.
91
95
  validateTrafficTypeExistance(log, readinessManager, storage.splits, mode, trafficTypeName, 'track');
92
- return eventTracker.track(eventData, size);
96
+ var result = eventTracker.track(eventData, size);
97
+ if (thenable(result)) {
98
+ return result.then(function (result) {
99
+ stopTelemetryTracker();
100
+ return result;
101
+ });
102
+ }
103
+ else {
104
+ stopTelemetryTracker();
105
+ return result;
106
+ }
93
107
  }
94
108
  return {
95
109
  getTreatment: getTreatment,
@@ -6,7 +6,7 @@ import { clientInputValidationDecorator } from './clientInputValidation';
6
6
  * Creates an Sdk client, i.e., a base client with status and destroy interface
7
7
  */
8
8
  export function sdkClientFactory(params, isSharedClient) {
9
- var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings;
9
+ var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings, telemetryTracker = params.telemetryTracker;
10
10
  return objectAssign(
11
11
  // Proto-linkage of the readiness Event Emitter
12
12
  Object.create(sdkReadinessManager.sdkStatus),
@@ -15,6 +15,9 @@ export function sdkClientFactory(params, isSharedClient) {
15
15
  // Sdk destroy
16
16
  {
17
17
  destroy: function () {
18
+ // record stat before flushing data
19
+ if (!isSharedClient)
20
+ telemetryTracker.sessionLength();
18
21
  // Stop background jobs
19
22
  syncManager && syncManager.stop();
20
23
  var flush = syncManager ? syncManager.flush() : Promise.resolve();
@@ -1,6 +1,7 @@
1
1
  import { sdkReadinessManagerFactory } from '../readiness/sdkReadinessManager';
2
2
  import { impressionsTrackerFactory } from '../trackers/impressionsTracker';
3
3
  import { eventTrackerFactory } from '../trackers/eventTracker';
4
+ import { telemetryTrackerFactory } from '../trackers/telemetryTracker';
4
5
  import { getMatching } from '../utils/key';
5
6
  import { shouldBeOptimized } from '../trackers/impressionObserver/utils';
6
7
  import { validateAndTrackApiKey } from '../utils/inputValidation/apiKey';
@@ -15,12 +16,12 @@ import { objectAssign } from '../utils/lang/objectAssign';
15
16
  export function sdkFactory(params) {
16
17
  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;
17
18
  var log = settings.log;
18
- // @TODO handle non-recoverable errors: not start sync, mark the SDK as destroyed, etc.
19
+ // @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid API Key, etc.
20
+ // On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
19
21
  // We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
20
22
  validateAndTrackApiKey(log, settings.core.authorizationKey);
21
- // @TODO handle non-recoverable error, such as, `fetch` api not available, invalid API Key, etc.
22
23
  var sdkReadinessManager = sdkReadinessManagerFactory(log, platform.EventEmitter, settings.startup.readyTimeout);
23
- var readinessManager = sdkReadinessManager.readinessManager;
24
+ var readiness = sdkReadinessManager.readinessManager;
24
25
  // @TODO consider passing the settings object, so that each storage access only what it needs
25
26
  var storageFactoryParams = {
26
27
  impressionsQueueSize: settings.scheduler.impressionsQueueSize,
@@ -36,32 +37,28 @@ export function sdkFactory(params) {
36
37
  onReadyCb: function (error) {
37
38
  if (error)
38
39
  return; // Don't emit SDK_READY if storage failed to connect. Error message is logged by wrapperAdapter
39
- readinessManager.splits.emit(SDK_SPLITS_ARRIVED);
40
- readinessManager.segments.emit(SDK_SEGMENTS_ARRIVED);
40
+ readiness.splits.emit(SDK_SPLITS_ARRIVED);
41
+ readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
41
42
  },
42
43
  metadata: metadataBuilder(settings),
43
44
  log: log
44
45
  };
45
46
  var storage = storageFactory(storageFactoryParams);
46
47
  // @TODO add support for dataloader: `if (params.dataLoader) params.dataLoader(storage);`
47
- // splitApi is used by SyncManager and Browser signal listener
48
- var splitApi = splitApiFactory && splitApiFactory(settings, platform);
49
- var syncManager = syncManagerFactory && syncManagerFactory({
50
- settings: settings,
51
- splitApi: splitApi,
52
- storage: storage,
53
- readiness: sdkReadinessManager.readinessManager,
54
- platform: platform
55
- });
56
48
  var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage });
57
49
  // trackers
58
50
  var observer = impressionsObserverFactory && impressionsObserverFactory();
59
- var impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, integrationsManager, observer, storage.impressionCounts);
60
- var eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager);
61
- // signal listener
51
+ var impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, integrationsManager, observer, storage.impressionCounts, storage.telemetry);
52
+ var eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager, storage.telemetry);
53
+ var telemetryTracker = telemetryTrackerFactory(storage.telemetry, platform.now);
54
+ // splitApi is used by SyncManager and Browser signal listener
55
+ var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
56
+ var ctx = { splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform };
57
+ var syncManager = syncManagerFactory && syncManagerFactory(ctx);
58
+ ctx.syncManager = syncManager;
62
59
  var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
63
- // Sdk client and manager
64
- var ctx = { eventTracker: eventTracker, impressionsTracker: impressionsTracker, sdkReadinessManager: sdkReadinessManager, settings: settings, storage: storage, syncManager: syncManager, signalListener: signalListener };
60
+ ctx.signalListener = signalListener;
61
+ // SDK client and manager
65
62
  var clientMethod = sdkClientMethodFactory(ctx);
66
63
  var managerInstance = sdkManagerFactory(log, storage.splits, sdkReadinessManager);
67
64
  syncManager && syncManager.start();
@@ -1,5 +1,6 @@
1
1
  import { splitHttpClientFactory } from './splitHttpClient';
2
2
  import { objectAssign } from '../utils/lang/objectAssign';
3
+ import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MY_SEGMENT } from '../utils/constants';
3
4
  var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
4
5
  function userKeyToQueryParam(userKey) {
5
6
  return 'users=' + encodeURIComponent(userKey); // no need to check availability of `encodeURIComponent`, since it is a global highly supported.
@@ -10,7 +11,7 @@ function userKeyToQueryParam(userKey) {
10
11
  * @param settings validated settings object
11
12
  * @param platform object containing environment-specific `getFetch` and `getOptions` dependencies
12
13
  */
13
- export function splitApiFactory(settings, platform) {
14
+ export function splitApiFactory(settings, platform, telemetryTracker) {
14
15
  var urls = settings.urls;
15
16
  var filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
16
17
  var SplitSDKImpressionsMode = settings.sync.impressionsMode;
@@ -31,15 +32,15 @@ export function splitApiFactory(settings, platform) {
31
32
  if (queryParams) // accounting the possibility that `userKeys` and thus `queryParams` are empty
32
33
  url += '?' + queryParams;
33
34
  }
34
- return splitHttpClient(url);
35
+ return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
35
36
  },
36
37
  fetchSplitChanges: function (since, noCache) {
37
38
  var url = urls.sdk + "/splitChanges?since=" + since + (filterQueryString || '');
38
- return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
39
+ return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS));
39
40
  },
40
41
  fetchSegmentChanges: function (since, segmentName, noCache) {
41
42
  var url = urls.sdk + "/segmentChanges/" + segmentName + "?since=" + since;
42
- return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
43
+ return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
43
44
  },
44
45
  fetchMySegments: function (userMatchingKey, noCache) {
45
46
  /**
@@ -49,7 +50,7 @@ export function splitApiFactory(settings, platform) {
49
50
  * - match user keys with special characters. E.g.: 'foo%bar', 'foo/bar'
50
51
  */
51
52
  var url = urls.sdk + "/mySegments/" + encodeURIComponent(userMatchingKey);
52
- return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
53
+ return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MY_SEGMENT));
53
54
  },
54
55
  /**
55
56
  * Post events.
@@ -59,7 +60,7 @@ export function splitApiFactory(settings, platform) {
59
60
  */
60
61
  postEventsBulk: function (body, headers) {
61
62
  var url = urls.events + "/events/bulk";
62
- return splitHttpClient(url, { method: 'POST', body: body, headers: headers });
63
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(EVENTS));
63
64
  },
64
65
  /**
65
66
  * Post impressions.
@@ -74,7 +75,7 @@ export function splitApiFactory(settings, platform) {
74
75
  method: 'POST',
75
76
  body: body,
76
77
  headers: objectAssign({ SplitSDKImpressionsMode: SplitSDKImpressionsMode }, headers)
77
- });
78
+ }, telemetryTracker.trackHttp(IMPRESSIONS));
78
79
  },
79
80
  /**
80
81
  * Post impressions counts.
@@ -84,15 +85,15 @@ export function splitApiFactory(settings, platform) {
84
85
  */
85
86
  postTestImpressionsCount: function (body, headers) {
86
87
  var url = urls.events + "/testImpressions/count";
87
- return splitHttpClient(url, { method: 'POST', body: body, headers: headers });
88
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(IMPRESSIONS_COUNT));
88
89
  },
89
- postMetricsCounters: function (body) {
90
- var url = urls.events + "/metrics/counters";
91
- return splitHttpClient(url, { method: 'POST', body: body }, true);
90
+ postMetricsConfig: function (body) {
91
+ var url = urls.telemetry + "/v1/metrics/config";
92
+ return splitHttpClient(url, { method: 'POST', body: body }, telemetryTracker.trackHttp(TELEMETRY), true);
92
93
  },
93
- postMetricsTimes: function (body) {
94
- var url = urls.events + "/metrics/times";
95
- return splitHttpClient(url, { method: 'POST', body: body }, true);
94
+ postMetricsUsage: function (body) {
95
+ var url = urls.telemetry + "/v1/metrics/usage";
96
+ return splitHttpClient(url, { method: 'POST', body: body }, telemetryTracker.trackHttp(TELEMETRY), true);
96
97
  }
97
98
  };
98
99
  }
@@ -25,8 +25,9 @@ export function splitHttpClientFactory(settings, getFetch, getOptions) {
25
25
  headers['SplitSDKMachineIP'] = ip;
26
26
  if (hostname)
27
27
  headers['SplitSDKMachineName'] = hostname;
28
- return function httpClient(url, reqOpts, logErrorsAsInfo) {
28
+ return function httpClient(url, reqOpts, latencyTracker, logErrorsAsInfo) {
29
29
  if (reqOpts === void 0) { reqOpts = {}; }
30
+ if (latencyTracker === void 0) { latencyTracker = function () { }; }
30
31
  if (logErrorsAsInfo === void 0) { logErrorsAsInfo = false; }
31
32
  var request = objectAssign({
32
33
  headers: reqOpts.headers ? objectAssign({}, headers, reqOpts.headers) : headers,
@@ -40,6 +41,7 @@ export function splitHttpClientFactory(settings, getFetch, getOptions) {
40
41
  if (!response.ok) {
41
42
  return response.text().then(function (message) { return Promise.reject({ response: response, message: message }); });
42
43
  }
44
+ latencyTracker();
43
45
  return response;
44
46
  })
45
47
  .catch(function (error) {
@@ -65,6 +67,7 @@ export function splitHttpClientFactory(settings, getFetch, getOptions) {
65
67
  var networkError = new Error(msg);
66
68
  // passes `undefined` as statusCode if not an HTTP error (resp === undefined)
67
69
  networkError.statusCode = resp && resp.status;
70
+ latencyTracker(networkError);
68
71
  throw networkError;
69
72
  }) : Promise.reject(new Error(messageNoFetch));
70
73
  };
@@ -10,11 +10,6 @@ var AbstractSegmentsCacheSync = /** @class */ (function () {
10
10
  * For client-side synchronizer: the method is not used.
11
11
  */
12
12
  AbstractSegmentsCacheSync.prototype.registerSegments = function (names) { return false; };
13
- /**
14
- * For server-side synchronizer: get the list of segments in the cache.
15
- * For client-side synchronizer: the method is not used.
16
- */
17
- AbstractSegmentsCacheSync.prototype.getRegisteredSegments = function () { return []; };
18
13
  /**
19
14
  * For server-side synchronizer: set the change number of `name` segment.
20
15
  * For client-side synchronizer: the method is not used.
@@ -1,8 +1,12 @@
1
1
  import { __extends } from "tslib";
2
2
  import { KeyBuilder } from './KeyBuilder';
3
- // NOT USED
4
- // const everythingAfterCount = /count\.([^/]+)$/;
5
- // const latencyMetricNameAndBucket = /latency\.([^/]+)\.bucket\.([0-9]+)$/;
3
+ var methodNames = {
4
+ t: 'treatment',
5
+ ts: 'treatments',
6
+ tc: 'treatmentWithConfig',
7
+ tcs: 'treatmentsWithConfig',
8
+ tr: 'track'
9
+ };
6
10
  var KeyBuilderSS = /** @class */ (function (_super) {
7
11
  __extends(KeyBuilderSS, _super);
8
12
  function KeyBuilderSS(prefix, metadata) {
@@ -14,7 +18,7 @@ var KeyBuilderSS = /** @class */ (function (_super) {
14
18
  return this.prefix + ".segments.registered";
15
19
  };
16
20
  KeyBuilderSS.prototype.buildVersionablePrefix = function () {
17
- return this.prefix + "/" + this.metadata.s + "/" + this.metadata.i;
21
+ return this.metadata.s + "/" + this.metadata.n + "/" + this.metadata.i;
18
22
  };
19
23
  KeyBuilderSS.prototype.buildImpressionsKey = function () {
20
24
  return this.prefix + ".impressions";
@@ -22,23 +26,12 @@ var KeyBuilderSS = /** @class */ (function (_super) {
22
26
  KeyBuilderSS.prototype.buildEventsKey = function () {
23
27
  return this.prefix + ".events";
24
28
  };
25
- KeyBuilderSS.prototype.buildLatencyKeyPrefix = function () {
26
- return this.buildVersionablePrefix() + "/latency";
29
+ KeyBuilderSS.prototype.buildLatencyKey = function (method, bucket) {
30
+ return this.prefix + ".telemetry.latencies::" + this.buildVersionablePrefix() + "/" + methodNames[method] + "/" + bucket;
27
31
  };
28
- KeyBuilderSS.prototype.buildLatencyKey = function (metricName, bucketNumber) {
29
- return this.buildLatencyKeyPrefix() + "." + metricName + ".bucket." + bucketNumber;
32
+ KeyBuilderSS.prototype.buildExceptionKey = function (method) {
33
+ return this.prefix + ".telemetry.exceptions::" + this.buildVersionablePrefix() + "/" + methodNames[method];
30
34
  };
31
- KeyBuilderSS.prototype.buildCountKey = function (metricName) {
32
- return this.buildVersionablePrefix() + "/count." + metricName;
33
- };
34
- // NOT USED
35
- // buildGaugeKey(metricName: string) {
36
- // return `${this.buildVersionablePrefix()}/gauge.${metricName}`;
37
- // }
38
- // NOT USED
39
- // searchPatternForCountKeys() {
40
- // return `${this.buildVersionablePrefix()}/count.*`;
41
- // }
42
35
  KeyBuilderSS.prototype.searchPatternForSplitKeys = function () {
43
36
  return this.buildSplitKeyPrefix() + "*";
44
37
  };
@@ -1,9 +1,14 @@
1
1
  import { isNaNNumber } from '../utils/lang';
2
- // @TODO add unit tests
3
- export function findLatencyIndex(latency, min, max, base) {
4
- if (min === void 0) { min = 0; }
5
- if (max === void 0) { max = 23; }
6
- if (base === void 0) { base = 1.5; }
7
- var index = Math.min(max, Math.max(min, Math.floor(Math.log(latency) / Math.log(base))));
2
+ var MIN = 0;
3
+ var MAX = 22;
4
+ var BASE = 1.5;
5
+ /**
6
+ * Calculates buckets from latency in milliseconds
7
+ *
8
+ * @param latencyInMs
9
+ * @returns a bucket index from 0 to 22 inclusive
10
+ */
11
+ export function findLatencyIndex(latencyInMs) {
12
+ var index = Math.min(MAX, Math.max(MIN, Math.ceil(Math.log(latencyInMs) / Math.log(BASE))));
8
13
  return isNaNNumber(index) ? 0 : index; // index is NaN if latency is not a positive number
9
14
  }
@@ -62,7 +62,7 @@ var MySegmentsCacheInLocal = /** @class */ (function (_super) {
62
62
  accum.push(segmentName);
63
63
  }
64
64
  else {
65
- // @BREAKING: This is only to clean up "old" keys. Remove this whole else code block.
65
+ // @TODO @BREAKING: This is only to clean up "old" keys. Remove this whole else code block and reuse `getRegisteredSegments` method.
66
66
  segmentName = _this.keys.extractOldSegmentKey(key);
67
67
  if (segmentName) { // this was an old segment key, let's clean up.
68
68
  var newSegmentKey = _this.keys.buildSegmentNameKey(segmentName);
@@ -104,6 +104,18 @@ var MySegmentsCacheInLocal = /** @class */ (function (_super) {
104
104
  }
105
105
  return isDiff;
106
106
  };
107
+ MySegmentsCacheInLocal.prototype.getRegisteredSegments = function () {
108
+ var _this = this;
109
+ return Object.keys(localStorage).reduce(function (accum, key) {
110
+ var segmentName = _this.keys.extractSegmentName(key);
111
+ if (segmentName)
112
+ accum.push(segmentName);
113
+ return accum;
114
+ }, []);
115
+ };
116
+ MySegmentsCacheInLocal.prototype.getKeysCount = function () {
117
+ return 1;
118
+ };
107
119
  return MySegmentsCacheInLocal;
108
120
  }(AbstractSegmentsCacheSync));
109
121
  export { MySegmentsCacheInLocal };
@@ -11,7 +11,8 @@ import { SplitsCacheInMemory } from '../inMemory/SplitsCacheInMemory';
11
11
  import { DEFAULT_CACHE_EXPIRATION_IN_MILLIS } from '../../utils/constants/browser';
12
12
  import { InMemoryStorageCSFactory } from '../inMemory/InMemoryStorageCS';
13
13
  import { LOG_PREFIX } from './constants';
14
- import { STORAGE_LOCALSTORAGE } from '../../utils/constants';
14
+ import { LOCALHOST_MODE, STORAGE_LOCALSTORAGE } from '../../utils/constants';
15
+ import { shouldRecordTelemetry, TelemetryCacheInMemory } from '../inMemory/TelemetryCacheInMemory';
15
16
  /**
16
17
  * InLocal storage factory for standalone client-side SplitFactory
17
18
  */
@@ -21,7 +22,7 @@ export function InLocalStorage(options) {
21
22
  function InLocalStorageCSFactory(params) {
22
23
  // Fallback to InMemoryStorage if LocalStorage API is not available
23
24
  if (!isLocalStorageAvailable()) {
24
- params.log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Fallbacking into default MEMORY storage');
25
+ params.log.warn(LOG_PREFIX + 'LocalStorage API is unavailable. Falling back to default MEMORY storage');
25
26
  return InMemoryStorageCSFactory(params);
26
27
  }
27
28
  var log = params.log;
@@ -33,6 +34,7 @@ export function InLocalStorage(options) {
33
34
  impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
34
35
  impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
35
36
  events: new EventsCacheInMemory(params.eventsQueueSize),
37
+ telemetry: params.mode !== LOCALHOST_MODE && shouldRecordTelemetry() ? new TelemetryCacheInMemory() : undefined,
36
38
  destroy: function () {
37
39
  this.splits = new SplitsCacheInMemory();
38
40
  this.segments = new MySegmentsCacheInMemory();
@@ -49,6 +51,7 @@ export function InLocalStorage(options) {
49
51
  impressions: this.impressions,
50
52
  impressionCounts: this.impressionCounts,
51
53
  events: this.events,
54
+ telemetry: this.telemetry,
52
55
  destroy: function () {
53
56
  this.splits = new SplitsCacheInMemory();
54
57
  this.segments = new MySegmentsCacheInMemory();
@@ -3,7 +3,8 @@ import { SegmentsCacheInMemory } from './SegmentsCacheInMemory';
3
3
  import { ImpressionsCacheInMemory } from './ImpressionsCacheInMemory';
4
4
  import { EventsCacheInMemory } from './EventsCacheInMemory';
5
5
  import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
6
- import { STORAGE_MEMORY } from '../../utils/constants';
6
+ import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
7
+ import { TelemetryCacheInMemory } from './TelemetryCacheInMemory';
7
8
  /**
8
9
  * InMemory storage factory for standalone server-side SplitFactory
9
10
  *
@@ -16,6 +17,7 @@ export function InMemoryStorageFactory(params) {
16
17
  impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
17
18
  impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
18
19
  events: new EventsCacheInMemory(params.eventsQueueSize),
20
+ telemetry: params.mode !== LOCALHOST_MODE ? new TelemetryCacheInMemory() : undefined,
19
21
  // When using MEMORY we should clean all the caches to leave them empty
20
22
  destroy: function () {
21
23
  this.splits.clear();
@@ -3,7 +3,8 @@ import { MySegmentsCacheInMemory } from './MySegmentsCacheInMemory';
3
3
  import { ImpressionsCacheInMemory } from './ImpressionsCacheInMemory';
4
4
  import { EventsCacheInMemory } from './EventsCacheInMemory';
5
5
  import { ImpressionCountsCacheInMemory } from './ImpressionCountsCacheInMemory';
6
- import { STORAGE_MEMORY } from '../../utils/constants';
6
+ import { LOCALHOST_MODE, STORAGE_MEMORY } from '../../utils/constants';
7
+ import { shouldRecordTelemetry, TelemetryCacheInMemory } from './TelemetryCacheInMemory';
7
8
  /**
8
9
  * InMemory storage factory for standalone client-side SplitFactory
9
10
  *
@@ -16,6 +17,7 @@ export function InMemoryStorageCSFactory(params) {
16
17
  impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
17
18
  impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
18
19
  events: new EventsCacheInMemory(params.eventsQueueSize),
20
+ telemetry: params.mode !== LOCALHOST_MODE && shouldRecordTelemetry() ? new TelemetryCacheInMemory() : undefined,
19
21
  // When using MEMORY we should clean all the caches to leave them empty
20
22
  destroy: function () {
21
23
  this.splits.clear();
@@ -32,6 +34,7 @@ export function InMemoryStorageCSFactory(params) {
32
34
  impressions: this.impressions,
33
35
  impressionCounts: this.impressionCounts,
34
36
  events: this.events,
37
+ telemetry: this.telemetry,
35
38
  // Set a new splits cache to clean it for the client without affecting other clients
36
39
  destroy: function () {
37
40
  this.splits = new SplitsCacheInMemory();
@@ -63,6 +63,12 @@ var MySegmentsCacheInMemory = /** @class */ (function (_super) {
63
63
  }
64
64
  return isDiff;
65
65
  };
66
+ MySegmentsCacheInMemory.prototype.getRegisteredSegments = function () {
67
+ return Object.keys(this.segmentCache);
68
+ };
69
+ MySegmentsCacheInMemory.prototype.getKeysCount = function () {
70
+ return 1;
71
+ };
66
72
  return MySegmentsCacheInMemory;
67
73
  }(AbstractSegmentsCacheSync));
68
74
  export { MySegmentsCacheInMemory };
@@ -54,6 +54,12 @@ var SegmentsCacheInMemory = /** @class */ (function (_super) {
54
54
  SegmentsCacheInMemory.prototype.getRegisteredSegments = function () {
55
55
  return Object.keys(this.segmentCache);
56
56
  };
57
+ SegmentsCacheInMemory.prototype.getKeysCount = function () {
58
+ var _this = this;
59
+ return Object.keys(this.segmentCache).reduce(function (acum, segmentName) {
60
+ return acum + _this.segmentCache[segmentName].size;
61
+ }, 0);
62
+ };
57
63
  SegmentsCacheInMemory.prototype.setChangeNumber = function (name, changeNumber) {
58
64
  this.segmentChangeNumber[name] = changeNumber;
59
65
  return true;