@splitsoftware/splitio-commons 3.1.1-rc.10 → 3.1.1-rc.12

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 (237) hide show
  1. package/CHANGES.txt +3 -0
  2. package/cjs/evaluator/condition/index.js +2 -2
  3. package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  4. package/cjs/evaluator/index.js +81 -71
  5. package/cjs/listeners/browser.js +2 -1
  6. package/cjs/listeners/node.js +4 -4
  7. package/cjs/logger/constants.js +15 -20
  8. package/cjs/logger/messages/debug.js +5 -6
  9. package/cjs/logger/messages/error.js +3 -3
  10. package/cjs/logger/messages/info.js +3 -4
  11. package/cjs/logger/messages/warn.js +6 -7
  12. package/cjs/platform/browser.js +15 -0
  13. package/cjs/platform/getEventSource/browser.js +8 -0
  14. package/cjs/platform/getEventSource/eventsource.js +480 -0
  15. package/cjs/platform/getEventSource/node.js +26 -0
  16. package/cjs/platform/getFetch/browser.js +9 -0
  17. package/cjs/platform/getFetch/node.js +27 -0
  18. package/cjs/platform/getOptions/node.js +25 -0
  19. package/cjs/platform/node.js +17 -0
  20. package/cjs/presets/serverSide.js +2 -2
  21. package/cjs/readiness/constants.js +5 -4
  22. package/cjs/readiness/readinessManager.js +23 -23
  23. package/cjs/readiness/sdkReadinessManager.js +1 -17
  24. package/cjs/sdkClient/client.js +24 -50
  25. package/cjs/sdkClient/clientInputValidation.js +6 -17
  26. package/cjs/sdkClient/sdkClient.js +3 -60
  27. package/cjs/sdkClient/sdkLifecycle.js +74 -0
  28. package/cjs/sdkClient/trackMethod.js +56 -0
  29. package/cjs/sdkFactory/index.js +11 -15
  30. package/cjs/sdkManager/index.js +5 -5
  31. package/cjs/services/authProvider.js +80 -0
  32. package/cjs/services/decorateHeaders.js +2 -1
  33. package/cjs/{sync/streaming/AuthClient/index.js → services/fetchAuth.js} +15 -16
  34. package/cjs/services/secureSplitHttpClient.js +36 -0
  35. package/cjs/services/serviceApi.js +147 -0
  36. package/cjs/services/splitApi.js +24 -10
  37. package/cjs/services/splitHttpClient.js +3 -5
  38. package/cjs/storages/AbstractDefinitionsCacheAsync.js +51 -0
  39. package/cjs/storages/AbstractDefinitionsCacheSync.js +76 -0
  40. package/cjs/storages/KeyBuilder.js +6 -6
  41. package/cjs/storages/KeyBuilderCS.js +5 -5
  42. package/cjs/storages/KeyBuilderSS.js +2 -2
  43. package/cjs/storages/getRolloutPlan.js +3 -3
  44. package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +195 -0
  45. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -2
  46. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +12 -11
  47. package/cjs/storages/inLocalStorage/index.js +6 -6
  48. package/cjs/storages/inLocalStorage/validateCache.js +3 -3
  49. package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +122 -0
  50. package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
  51. package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
  52. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +7 -6
  53. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  54. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  55. package/cjs/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +79 -77
  56. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +4 -2
  57. package/cjs/storages/inRedis/index.js +2 -2
  58. package/cjs/storages/pluggable/DefinitionsCachePluggable.js +214 -0
  59. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +4 -2
  60. package/cjs/storages/pluggable/index.js +2 -2
  61. package/cjs/storages/setRolloutPlan.js +4 -4
  62. package/cjs/storages/utils.js +1 -0
  63. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
  64. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +24 -15
  65. package/cjs/sync/polling/pollingManagerCS.js +86 -81
  66. package/cjs/sync/polling/pollingManagerSS.js +44 -36
  67. package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +13 -0
  68. package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
  69. package/cjs/sync/polling/updaters/definitionChangesUpdater.js +207 -0
  70. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  71. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
  72. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
  73. package/cjs/sync/streaming/SSEHandler/index.js +2 -1
  74. package/cjs/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +19 -20
  75. package/cjs/sync/streaming/constants.js +4 -3
  76. package/cjs/sync/streaming/parseUtils.js +14 -14
  77. package/cjs/sync/streaming/pushManager.js +22 -26
  78. package/cjs/sync/submitters/eventsSubmitter.js +1 -1
  79. package/cjs/sync/submitters/impressionCountsSubmitter.js +1 -1
  80. package/cjs/sync/submitters/impressionsSubmitter.js +5 -4
  81. package/cjs/sync/submitters/telemetrySubmitter.js +3 -4
  82. package/cjs/sync/submitters/uniqueKeysSubmitter.js +1 -1
  83. package/cjs/sync/syncManagerOnline.js +5 -5
  84. package/cjs/utils/Backoff.js +35 -3
  85. package/cjs/utils/EventEmitter.js +391 -0
  86. package/cjs/utils/filter/bloomFilter.js +37 -0
  87. package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
  88. package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
  89. package/cjs/utils/inputValidation/definitions.js +25 -0
  90. package/cjs/utils/inputValidation/index.js +7 -7
  91. package/cjs/utils/inputValidation/isOperational.js +4 -4
  92. package/cjs/utils/inputValidation/target.js +22 -0
  93. package/cjs/utils/labels/index.js +3 -3
  94. package/cjs/utils/settingsValidation/index.js +2 -0
  95. package/cjs/utils/settingsValidation/splitFilters.js +3 -3
  96. package/cjs/utils/settingsValidation/url.js +6 -2
  97. package/esm/evaluator/condition/index.js +2 -2
  98. package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  99. package/esm/evaluator/index.js +80 -71
  100. package/esm/listeners/browser.js +2 -1
  101. package/esm/listeners/node.js +4 -4
  102. package/esm/logger/constants.js +12 -17
  103. package/esm/logger/messages/debug.js +5 -6
  104. package/esm/logger/messages/error.js +3 -3
  105. package/esm/logger/messages/info.js +3 -4
  106. package/esm/logger/messages/warn.js +6 -7
  107. package/esm/platform/browser.js +12 -0
  108. package/esm/platform/getEventSource/browser.js +4 -0
  109. package/esm/platform/getEventSource/eventsource.js +480 -0
  110. package/esm/platform/getEventSource/node.js +20 -0
  111. package/esm/platform/getFetch/browser.js +5 -0
  112. package/esm/platform/getFetch/node.js +22 -0
  113. package/esm/platform/getOptions/node.js +20 -0
  114. package/esm/platform/node.js +14 -0
  115. package/esm/presets/serverSide.js +2 -2
  116. package/esm/readiness/constants.js +4 -3
  117. package/esm/readiness/readinessManager.js +24 -24
  118. package/esm/readiness/sdkReadinessManager.js +2 -18
  119. package/esm/sdkClient/client.js +23 -50
  120. package/esm/sdkClient/clientInputValidation.js +8 -19
  121. package/esm/sdkClient/sdkClient.js +3 -60
  122. package/esm/sdkClient/sdkLifecycle.js +70 -0
  123. package/esm/sdkClient/trackMethod.js +52 -0
  124. package/esm/sdkFactory/index.js +12 -16
  125. package/esm/sdkManager/index.js +6 -6
  126. package/esm/services/authProvider.js +76 -0
  127. package/esm/services/decorateHeaders.js +2 -1
  128. package/esm/{sync/streaming/AuthClient/index.js → services/fetchAuth.js} +13 -13
  129. package/esm/services/secureSplitHttpClient.js +32 -0
  130. package/esm/services/serviceApi.js +143 -0
  131. package/esm/services/splitApi.js +24 -10
  132. package/esm/services/splitHttpClient.js +3 -5
  133. package/esm/storages/AbstractDefinitionsCacheAsync.js +48 -0
  134. package/esm/storages/AbstractDefinitionsCacheSync.js +71 -0
  135. package/esm/storages/KeyBuilder.js +6 -6
  136. package/esm/storages/KeyBuilderCS.js +5 -5
  137. package/esm/storages/KeyBuilderSS.js +2 -2
  138. package/esm/storages/getRolloutPlan.js +3 -3
  139. package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +192 -0
  140. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -2
  141. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +9 -8
  142. package/esm/storages/inLocalStorage/index.js +6 -6
  143. package/esm/storages/inLocalStorage/validateCache.js +3 -3
  144. package/esm/storages/inMemory/DefinitionsCacheInMemory.js +119 -0
  145. package/esm/storages/inMemory/InMemoryStorage.js +4 -4
  146. package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
  147. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +4 -3
  148. package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  149. package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  150. package/esm/storages/inRedis/{SplitsCacheInRedis.js → DefinitionsCacheInRedis.js} +78 -76
  151. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +4 -2
  152. package/esm/storages/inRedis/index.js +2 -2
  153. package/esm/storages/pluggable/DefinitionsCachePluggable.js +211 -0
  154. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +4 -2
  155. package/esm/storages/pluggable/index.js +2 -2
  156. package/esm/storages/setRolloutPlan.js +4 -4
  157. package/esm/storages/utils.js +1 -0
  158. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
  159. package/esm/sync/polling/fetchers/splitChangesFetcher.js +25 -16
  160. package/esm/sync/polling/pollingManagerCS.js +87 -82
  161. package/esm/sync/polling/pollingManagerSS.js +44 -36
  162. package/esm/sync/polling/syncTasks/definitionsSyncTask.js +9 -0
  163. package/esm/sync/polling/syncTasks/segmentsSyncTask.js +2 -3
  164. package/esm/sync/polling/updaters/definitionChangesUpdater.js +201 -0
  165. package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  166. package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
  167. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
  168. package/esm/sync/streaming/SSEHandler/index.js +3 -2
  169. package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +19 -20
  170. package/esm/sync/streaming/constants.js +3 -2
  171. package/esm/sync/streaming/parseUtils.js +11 -11
  172. package/esm/sync/streaming/pushManager.js +24 -28
  173. package/esm/sync/submitters/eventsSubmitter.js +1 -1
  174. package/esm/sync/submitters/impressionCountsSubmitter.js +1 -1
  175. package/esm/sync/submitters/impressionsSubmitter.js +5 -4
  176. package/esm/sync/submitters/telemetrySubmitter.js +3 -4
  177. package/esm/sync/submitters/uniqueKeysSubmitter.js +1 -1
  178. package/esm/sync/syncManagerOnline.js +4 -4
  179. package/esm/utils/Backoff.js +35 -3
  180. package/esm/utils/EventEmitter.js +387 -0
  181. package/esm/utils/filter/bloomFilter.js +33 -0
  182. package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
  183. package/esm/utils/inputValidation/definitionExistence.js +15 -0
  184. package/esm/utils/inputValidation/definitions.js +21 -0
  185. package/esm/utils/inputValidation/index.js +3 -3
  186. package/esm/utils/inputValidation/isOperational.js +4 -4
  187. package/esm/utils/inputValidation/target.js +18 -0
  188. package/esm/utils/labels/index.js +2 -2
  189. package/esm/utils/settingsValidation/index.js +2 -0
  190. package/esm/utils/settingsValidation/splitFilters.js +3 -3
  191. package/esm/utils/settingsValidation/url.js +6 -2
  192. package/package.json +1 -1
  193. package/src/dtos/types.ts +4 -4
  194. package/src/services/authProvider.ts +2 -2
  195. package/src/{sync/streaming/AuthClient/index.ts → services/fetchAuth.ts} +3 -4
  196. package/src/services/splitApi.ts +1 -1
  197. package/src/services/types.ts +21 -4
  198. package/src/storages/AbstractDefinitionsCacheAsync.ts +3 -3
  199. package/src/storages/AbstractDefinitionsCacheSync.ts +2 -2
  200. package/src/storages/inLocalStorage/DefinitionsCacheInLocal.ts +2 -2
  201. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +3 -3
  202. package/src/storages/inMemory/DefinitionsCacheInMemory.ts +2 -2
  203. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +2 -2
  204. package/src/storages/inRedis/DefinitionsCacheInRedis.ts +6 -4
  205. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +7 -5
  206. package/src/storages/pluggable/DefinitionsCachePluggable.ts +4 -2
  207. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +5 -3
  208. package/src/storages/types.ts +6 -6
  209. package/src/sync/polling/fetchers/splitChangesFetcher.ts +5 -5
  210. package/src/sync/polling/types.ts +22 -1
  211. package/src/sync/polling/updaters/definitionChangesUpdater.ts +26 -20
  212. package/src/sync/streaming/SSEClient/index.ts +1 -1
  213. package/src/sync/streaming/SSEClient/types.ts +1 -1
  214. package/src/sync/streaming/UpdateWorkers/DefinitionsUpdateWorker.ts +15 -11
  215. package/src/sync/streaming/UpdateWorkers/types.ts +6 -0
  216. package/src/sync/streaming/parseUtils.ts +3 -4
  217. package/src/sync/streaming/pushManager.ts +4 -3
  218. package/cjs/storages/AbstractSplitsCacheAsync.js +0 -51
  219. package/cjs/storages/AbstractSplitsCacheSync.js +0 -76
  220. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -194
  221. package/cjs/storages/inMemory/SplitsCacheInMemory.js +0 -121
  222. package/cjs/storages/pluggable/SplitsCachePluggable.js +0 -212
  223. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
  224. package/cjs/sync/polling/updaters/splitChangesUpdater.js +0 -200
  225. package/cjs/sync/streaming/AuthClient/types.js +0 -2
  226. package/cjs/utils/inputValidation/splits.js +0 -25
  227. package/esm/storages/AbstractSplitsCacheAsync.js +0 -48
  228. package/esm/storages/AbstractSplitsCacheSync.js +0 -71
  229. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -191
  230. package/esm/storages/inMemory/SplitsCacheInMemory.js +0 -118
  231. package/esm/storages/pluggable/SplitsCachePluggable.js +0 -209
  232. package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
  233. package/esm/sync/polling/updaters/splitChangesUpdater.js +0 -194
  234. package/esm/sync/streaming/AuthClient/types.js +0 -1
  235. package/esm/utils/inputValidation/splitExistence.js +0 -15
  236. package/esm/utils/inputValidation/splits.js +0 -21
  237. package/src/sync/streaming/AuthClient/types.ts +0 -19
@@ -1,5 +1,5 @@
1
1
  import { SDK_SEGMENTS_ARRIVED, SEGMENTS_UPDATE } from '../../../readiness/constants';
2
- import { LOG_PREFIX_INSTANTIATION, LOG_PREFIX_SYNC_SEGMENTS } from '../../../logger/constants';
2
+ import { LOG_PREFIX_INSTANTIATION, LOG_PREFIX_SYNC } from '../../../logger/constants';
3
3
  import { timeout } from '../../../utils/promise/timeout';
4
4
  /**
5
5
  * Factory of SegmentChanges updater, a task that:
@@ -20,7 +20,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
20
20
  return promise;
21
21
  }
22
22
  function updateSegment(segmentName, noCache, till, fetchOnlyNew, retries) {
23
- log.debug("".concat(LOG_PREFIX_SYNC_SEGMENTS, "Processing segment ").concat(segmentName));
23
+ log.debug("".concat(LOG_PREFIX_SYNC, "Processing segment ").concat(segmentName));
24
24
  var sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
25
25
  return sincePromise.then(function (since) {
26
26
  // if fetchOnlyNew flag, avoid processing already fetched segments
@@ -28,14 +28,14 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
28
28
  false :
29
29
  segmentChangesFetcher(since || -1, segmentName, noCache, till, _promiseDecorator).then(function (changes) {
30
30
  return Promise.all(changes.map(function (x) {
31
- log.debug("".concat(LOG_PREFIX_SYNC_SEGMENTS, "Processing ").concat(segmentName, " with till = ").concat(x.till, ". Added: ").concat(x.added.length, ". Removed: ").concat(x.removed.length));
31
+ log.debug("".concat(LOG_PREFIX_SYNC, "Processing ").concat(segmentName, " with since = ").concat(x.since, " and till = ").concat(x.till, ". Added: ").concat(x.added.length, ". Removed: ").concat(x.removed.length));
32
32
  return segments.update(segmentName, x.added, x.removed, x.till);
33
33
  })).then(function (updates) {
34
34
  return updates.some(function (update) { return update; });
35
35
  });
36
36
  }).catch(function (error) {
37
37
  if (retries) {
38
- log.warn("".concat(LOG_PREFIX_SYNC_SEGMENTS, "Retrying fetch of segment ").concat(segmentName, " (attempt #").concat(retries, "). Reason: ").concat(error));
38
+ log.warn("".concat(LOG_PREFIX_SYNC, "Retrying fetch of segment ").concat(segmentName, " (attempt #").concat(retries, "). Reason: ").concat(error));
39
39
  return updateSegment(segmentName, noCache, till, fetchOnlyNew, retries - 1);
40
40
  }
41
41
  throw error;
@@ -54,7 +54,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
54
54
  * @param till - till target for the provided segmentName, for CDN bypass.
55
55
  */
56
56
  return function segmentChangesUpdater(fetchOnlyNew, segmentName, noCache, till) {
57
- log.debug("".concat(LOG_PREFIX_SYNC_SEGMENTS, "Started segments update"));
57
+ log.debug("".concat(LOG_PREFIX_SYNC, "Started segments update"));
58
58
  // If not a segment name provided, read list of available segments names to be updated.
59
59
  var segmentsPromise = Promise.resolve(segmentName ? [segmentName] : segments.getRegisteredSegments());
60
60
  return segmentsPromise.then(function (segmentNames) {
@@ -63,7 +63,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
63
63
  // if at least one segment fetch succeeded, mark segments ready
64
64
  if (shouldUpdateFlags.some(function (update) { return update; }) || readyOnAlreadyExistentState) {
65
65
  readyOnAlreadyExistentState = false;
66
- if (readiness) {
66
+ if (readiness && !fetchOnlyNew) {
67
67
  var metadata = {
68
68
  type: SEGMENTS_UPDATE,
69
69
  names: []
@@ -84,7 +84,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
84
84
  log.error("".concat(LOG_PREFIX_INSTANTIATION, ": you passed a client-side type authorizationKey, please grab an SDK Key from Harness FME UI that is of type server-side."));
85
85
  }
86
86
  else {
87
- log.warn("".concat(LOG_PREFIX_SYNC_SEGMENTS, "Error while doing fetch of segments. ").concat(error));
87
+ log.warn("".concat(LOG_PREFIX_SYNC, "Error while doing fetch of segments. ").concat(error));
88
88
  }
89
89
  return false;
90
90
  });
@@ -1,5 +1,5 @@
1
1
  import { CONNECTION_ESTABLISHED, DISABLED, ENABLED, OCCUPANCY_PRI, OCCUPANCY_SEC, PAUSED, STREAMING_STATUS } from '../../../utils/constants';
2
- import { ControlType, PUSH_SUBSYSTEM_UP, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN } from '../constants';
2
+ import { ControlType, PUSH_SUBSYSTEM_UP, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN } from '../constants';
3
3
  var CONTROL_CHANNEL_REGEXS = [/control_pri$/, /control_sec$/];
4
4
  var STREAMING_EVENT_TYPES = [OCCUPANCY_PRI, OCCUPANCY_SEC];
5
5
  /**
@@ -70,7 +70,7 @@ export function notificationKeeperFactory(pushEmitter, telemetryTracker) {
70
70
  c.cTime = timestamp;
71
71
  if (controlType === ControlType.STREAMING_DISABLED) {
72
72
  telemetryTracker.streamingEvent(STREAMING_STATUS, DISABLED);
73
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
73
+ pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
74
74
  }
75
75
  else if (hasPublishers) {
76
76
  if (controlType === ControlType.STREAMING_PAUSED && hasResumed) {
@@ -1,6 +1,6 @@
1
1
  import { errorParser, messageParser } from './NotificationParser';
2
2
  import { notificationKeeperFactory } from './NotificationKeeper';
3
- import { PUSH_RETRYABLE_ERROR, PUSH_NONRETRYABLE_ERROR, OCCUPANCY, CONTROL, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, RB_SEGMENT_UPDATE } from '../constants';
3
+ import { PUSH_RETRYABLE_ERROR, PUSH_NON_RETRYABLE_ERROR, OCCUPANCY, CONTROL, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, CONFIG_UPDATE, MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, RB_SEGMENT_UPDATE } from '../constants';
4
4
  import { STREAMING_PARSING_ERROR_FAILS, ERROR_STREAMING_SSE, STREAMING_PARSING_MESSAGE_FAILS, STREAMING_NEW_MESSAGE } from '../../../logger/constants';
5
5
  import { ABLY_ERROR, NON_REQUESTED, SSE_CONNECTION_ERROR } from '../../../utils/constants';
6
6
  /**
@@ -48,7 +48,7 @@ export function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
48
48
  pushEmitter.emit(PUSH_RETRYABLE_ERROR);
49
49
  }
50
50
  else {
51
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
51
+ pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
52
52
  }
53
53
  },
54
54
  /* NotificationProcessor */
@@ -71,6 +71,7 @@ export function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
71
71
  switch (parsedData.type) {
72
72
  /* update events */
73
73
  case SPLIT_UPDATE:
74
+ case CONFIG_UPDATE:
74
75
  case SEGMENT_UPDATE:
75
76
  case MEMBERSHIPS_MS_UPDATE:
76
77
  case MEMBERSHIPS_LS_UPDATE:
@@ -1,40 +1,39 @@
1
1
  import { STREAMING_PARSING_SPLIT_UPDATE } from '../../../logger/constants';
2
- import { SDK_SPLITS_ARRIVED } from '../../../readiness/constants';
2
+ import { SDK_DEFINITIONS_ARRIVED } from '../../../readiness/constants';
3
3
  import { Backoff } from '../../../utils/Backoff';
4
4
  import { SPLITS } from '../../../utils/constants';
5
5
  import { RB_SEGMENT_UPDATE } from '../constants';
6
- import { parseFFUpdatePayload } from '../parseUtils';
6
+ import { parseUpdatePayload } from '../parseUtils';
7
7
  import { FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT, FETCH_BACKOFF_MAX_RETRIES } from './constants';
8
8
  /**
9
- * SplitsUpdateWorker factory
9
+ * DefinitionsUpdateWorker factory for Flags SDKs, where notifications pcn and changeNumber are environment-scoped
10
10
  */
11
- export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmitter, telemetryTracker, segmentsSyncTask) {
12
- var ff = SplitsUpdateWorker(storage.splits);
13
- var rbs = SplitsUpdateWorker(storage.rbSegments);
14
- function SplitsUpdateWorker(cache) {
11
+ export function DefinitionsUpdateWorker(params, pollingManager) {
12
+ var log = params.settings.log, storage = params.storage, telemetryTracker = params.telemetryTracker, definitionsEventEmitter = params.readiness.definitions;
13
+ var definitionsSyncTask = pollingManager.definitionsSyncTask;
14
+ var ff = DefinitionsUpdateWorker(storage.definitions);
15
+ var rbs = DefinitionsUpdateWorker(storage.rbSegments);
16
+ function DefinitionsUpdateWorker(cache) {
15
17
  var maxChangeNumber = -1;
16
18
  var handleNewEvent = false;
17
19
  var isHandlingEvent;
18
20
  var cdnBypass;
19
21
  var instantUpdate;
20
- var backoff = new Backoff(__handleSplitUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
21
- function __handleSplitUpdateCall() {
22
+ var backoff = new Backoff(__handleDefinitionUpdateCall, FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT);
23
+ function __handleDefinitionUpdateCall() {
22
24
  isHandlingEvent = true;
23
25
  if (maxChangeNumber > cache.getChangeNumber()) {
24
26
  handleNewEvent = false;
25
27
  // fetch splits revalidating data if cached
26
- splitsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(function () {
28
+ definitionsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(function () {
27
29
  if (!isHandlingEvent)
28
30
  return; // halt if `stop` has been called
29
31
  if (handleNewEvent) {
30
- __handleSplitUpdateCall();
32
+ __handleDefinitionUpdateCall();
31
33
  }
32
34
  else {
33
35
  if (instantUpdate)
34
36
  telemetryTracker.trackUpdatesFromSSE(SPLITS);
35
- // fetch new registered segments for server-side API. Not retrying on error
36
- if (segmentsSyncTask)
37
- segmentsSyncTask.execute(true);
38
37
  var attempts = backoff.attempts + 1;
39
38
  if (ff.isSync() && rbs.isSync()) {
40
39
  log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
@@ -52,7 +51,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
52
51
  else {
53
52
  backoff.reset();
54
53
  cdnBypass = true;
55
- __handleSplitUpdateCall();
54
+ __handleDefinitionUpdateCall();
56
55
  }
57
56
  }
58
57
  });
@@ -80,7 +79,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
80
79
  instantUpdate = { payload: payload, changeNumber: changeNumber, type: type };
81
80
  }
82
81
  if (backoff.timeoutID || !isHandlingEvent)
83
- __handleSplitUpdateCall();
82
+ __handleDefinitionUpdateCall();
84
83
  backoff.reset();
85
84
  },
86
85
  stop: function () {
@@ -96,7 +95,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
96
95
  put: function (parsedData) {
97
96
  if (parsedData.d && parsedData.c !== undefined) {
98
97
  try {
99
- var payload = parseFFUpdatePayload(parsedData.c, parsedData.d);
98
+ var payload = parseUpdatePayload(parsedData.c, parsedData.d);
100
99
  if (payload) {
101
100
  (parsedData.type === RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData, payload);
102
101
  return;
@@ -115,11 +114,11 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
115
114
  * @param splitName - name of split to kill
116
115
  * @param defaultTreatment - default treatment value
117
116
  */
118
- killSplit: function (_a) {
117
+ killDefinition: function (_a) {
119
118
  var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment;
120
- if (storage.splits.killLocally(splitName, defaultTreatment, changeNumber)) {
119
+ if (storage.definitions.killLocally(splitName, defaultTreatment, changeNumber)) {
121
120
  // trigger an SDK_UPDATE if Split was killed locally
122
- splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, true);
121
+ definitionsEventEmitter.emit(SDK_DEFINITIONS_ARRIVED, true);
123
122
  }
124
123
  // queues the SplitChanges fetch (only if changeNumber is newer)
125
124
  ff.put({ changeNumber: changeNumber });
@@ -5,7 +5,7 @@ export var SECONDS_BEFORE_EXPIRATION = 600;
5
5
  * emitted on SSE and Authenticate non-recoverable errors, STREAMING_DISABLED control notification and authentication with pushEnabled false
6
6
  * triggers `handleNonRetryableError` call
7
7
  */
8
- export var PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR';
8
+ export var PUSH_NON_RETRYABLE_ERROR = 'PUSH_NON_RETRYABLE_ERROR';
9
9
  /**
10
10
  * emitted on SSE and Authenticate recoverable errors
11
11
  * triggers `handleRetryableError` call
@@ -17,7 +17,7 @@ export var PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR';
17
17
  */
18
18
  export var PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
19
19
  /**
20
- * emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0, PUSH_NONRETRYABLE_ERROR and PUSH_RETRYABLE_ERROR events.
20
+ * emitted on STREAMING_PAUSED control notification, OCCUPANCY equal to 0, PUSH_NON_RETRYABLE_ERROR and PUSH_RETRYABLE_ERROR events.
21
21
  * triggers `startPolling` and `stopWorkers` calls
22
22
  */
23
23
  export var PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
@@ -27,6 +27,7 @@ export var MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
27
27
  export var SEGMENT_UPDATE = 'SEGMENT_UPDATE';
28
28
  export var SPLIT_KILL = 'SPLIT_KILL';
29
29
  export var SPLIT_UPDATE = 'SPLIT_UPDATE';
30
+ export var CONFIG_UPDATE = 'CONFIG_UPDATE';
30
31
  export var RB_SEGMENT_UPDATE = 'RB_SEGMENT_UPDATE';
31
32
  // Control-type push notifications, handled by NotificationKeeper
32
33
  export var CONTROL = 'CONTROL';
@@ -30,22 +30,22 @@ function decompress(data, compression) {
30
30
  throw new Error("Invalid compression algorithm #".concat(compression));
31
31
  }
32
32
  /**
33
- * Decode, decompress and parse the provided 'data' into a KeyList object
33
+ * Decode, decompress and parse the provided 'data' into an object of type T
34
34
  *
35
35
  * @param data - base64 encoded string
36
36
  * @param compression - 1 GZIP, 2 ZLIB
37
37
  * @param avoidPrecisionLoss - true as default, set it as false if dont need to avoid precission loss
38
- * @returns keyList
38
+ * @returns parsed object
39
39
  * @throws if data string cannot be decoded, decompressed or parsed
40
40
  */
41
- export function parseKeyList(data, compression, avoidPrecisionLoss) {
41
+ export function parseCompressedData(data, compression, avoidPrecisionLoss) {
42
42
  if (avoidPrecisionLoss === void 0) { avoidPrecisionLoss = true; }
43
- var binKeyList = decompress(data, compression);
44
- var strKeyList = Uint8ArrayToString(binKeyList);
45
- // replace numbers to strings, to avoid losing precision
43
+ var binData = decompress(data, compression);
44
+ var str = Uint8ArrayToString(binData);
45
+ // replace numbers to strings, to avoid losing precision (e.g., 64-bit IDs in KeyList)
46
46
  if (avoidPrecisionLoss)
47
- strKeyList = strKeyList.replace(/\d+/g, '"$&"');
48
- return JSON.parse(strKeyList);
47
+ str = str.replace(/\d+/g, '"$&"');
48
+ return JSON.parse(str);
49
49
  }
50
50
  /**
51
51
  * Decode, decompress and parse the provided 'data' into a Bitmap object
@@ -73,11 +73,11 @@ export function isInBitmap(bitmap, hash64hex) {
73
73
  return (bitmap[internal] & 1 << offset) > 0;
74
74
  }
75
75
  /**
76
- * Parse feature flags notifications for instant feature flag updates
76
+ * Parse notifications for instant updates
77
77
  */
78
- export function parseFFUpdatePayload(compression, data) {
78
+ export function parseUpdatePayload(compression, data) {
79
79
  return compression > 0 ?
80
- parseKeyList(data, compression, false) :
80
+ parseCompressedData(data, compression, false) :
81
81
  JSON.parse(decodeFromBase64(data));
82
82
  }
83
83
  var DEFAULT_MAX_INTERVAL = 60000;
@@ -3,15 +3,14 @@ import { Backoff } from '../../utils/Backoff';
3
3
  import { SSEHandlerFactory } from './SSEHandler';
4
4
  import { MySegmentsUpdateWorker } from './UpdateWorkers/MySegmentsUpdateWorker';
5
5
  import { SegmentsUpdateWorker } from './UpdateWorkers/SegmentsUpdateWorker';
6
- import { SplitsUpdateWorker } from './UpdateWorkers/SplitsUpdateWorker';
7
- import { authenticateFactory, hashUserKey } from './AuthClient';
6
+ import { DefinitionsUpdateWorker } from './UpdateWorkers/DefinitionsUpdateWorker';
8
7
  import { forOwn } from '../../utils/lang';
9
8
  import { SSEClient } from './SSEClient';
10
9
  import { checkIfServerSide, getMatching } from '../../utils/key';
11
- import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, RB_SEGMENT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
10
+ import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NON_RETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, CONFIG_UPDATE, RB_SEGMENT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
12
11
  import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE } from '../../logger/constants';
13
12
  import { UpdateStrategy } from './SSEHandler/types';
14
- import { getDelay, isInBitmap, parseBitmap, parseKeyList } from './parseUtils';
13
+ import { getDelay, isInBitmap, parseBitmap, parseCompressedData } from './parseUtils';
15
14
  import { hash64 } from '../../utils/murmur3/murmur3_64';
16
15
  import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
17
16
  /**
@@ -19,8 +18,9 @@ import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
19
18
  * - for server-side if key is not provided in settings.
20
19
  * - for client-side, with support for multiple clients, if key is provided in settings
21
20
  */
22
- export function pushManagerFactory(params, pollingManager) {
23
- var settings = params.settings, storage = params.storage, splitApi = params.splitApi, readiness = params.readiness, platform = params.platform, telemetryTracker = params.telemetryTracker;
21
+ export function pushManagerFactory(params, pollingManager, definitionsUpdateWorkerFactory) {
22
+ if (definitionsUpdateWorkerFactory === void 0) { definitionsUpdateWorkerFactory = DefinitionsUpdateWorker; }
23
+ var settings = params.settings, storage = params.storage, serviceApi = params.serviceApi, platform = params.platform, telemetryTracker = params.telemetryTracker;
24
24
  // `userKey` is the matching key of main client in client-side SDK.
25
25
  // It can be used to check if running on client-side or server-side SDK.
26
26
  var userKey = checkIfServerSide(settings) ? undefined : getMatching(settings.core.key);
@@ -34,7 +34,6 @@ export function pushManagerFactory(params, pollingManager) {
34
34
  log.warn(STREAMING_FALLBACK, [e]);
35
35
  return;
36
36
  }
37
- var authenticate = authenticateFactory(splitApi.fetchAuth);
38
37
  // init feedback loop
39
38
  var pushEmitter = new platform.EventEmitter();
40
39
  var sseHandler = SSEHandlerFactory(log, pushEmitter, telemetryTracker);
@@ -42,19 +41,17 @@ export function pushManagerFactory(params, pollingManager) {
42
41
  // init workers
43
42
  // MySegmentsUpdateWorker (client-side) are initiated in `add` method
44
43
  var segmentsUpdateWorker = userKey ? undefined : SegmentsUpdateWorker(log, pollingManager.segmentsSyncTask, storage.segments);
45
- // For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
46
- var splitsUpdateWorker = SplitsUpdateWorker(log, storage, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask);
47
- // [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
48
- var userKeyHashes = {};
44
+ // For server-side we pass the segmentsSyncTask, used by DefinitionsUpdateWorker to fetch new segments
45
+ var definitionsUpdateWorker = definitionsUpdateWorkerFactory(params, pollingManager);
49
46
  // [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
50
47
  // Hash64 is used to process membership update events and dispatch actions to the corresponding MySegmentsUpdateWorker.
51
48
  var clients = {};
52
49
  // [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
53
50
  var connectForNewClient = false;
54
- // flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a PUSH_NONRETRYABLE_ERROR error.
51
+ // flag that indicates if `stop/disconnectPush` was called, either by the SyncManager, when the client is destroyed, or due to a PUSH_NON_RETRYABLE_ERROR error.
55
52
  // It is used to halt the `connectPush` process if it was in progress.
56
53
  var disconnected;
57
- // flag that indicates a PUSH_NONRETRYABLE_ERROR, condition with which starting pushManager again is ignored.
54
+ // flag that indicates a PUSH_NON_RETRYABLE_ERROR, condition with which starting pushManager again is ignored.
58
55
  // true if STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE or Auth errors.
59
56
  var disabled; // `disabled` implies `disconnected === true`
60
57
  /** PushManager functions related to initialization */
@@ -90,14 +87,14 @@ export function pushManagerFactory(params, pollingManager) {
90
87
  log.info(STREAMING_CONNECTING);
91
88
  disconnected = false;
92
89
  var userKeys = userKey ? Object.keys(clients) : undefined;
93
- authenticate(userKeys).then(function (authData) {
90
+ serviceApi.fetchAuth(userKeys).then(function (authData) {
94
91
  if (disconnected)
95
92
  return;
96
- // 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
93
+ // 'pushEnabled: false' is handled as a PUSH_NON_RETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
97
94
  // close the sseClient in case the org has been bloqued while the instance was connected to streaming
98
95
  if (!authData.pushEnabled) {
99
96
  log.info(STREAMING_DISABLED);
100
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
97
+ pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
101
98
  return;
102
99
  }
103
100
  // [Only for client-side] don't open SSE connection if a new shared client was added, since it means that a new authentication is taking place
@@ -112,7 +109,7 @@ export function pushManagerFactory(params, pollingManager) {
112
109
  // Handle 4XX HTTP errors: 401 (invalid SDK Key) or 400 (using incorrect SDK Key, i.e., client-side SDK Key on server-side)
113
110
  if (error.statusCode >= 400 && error.statusCode < 500) {
114
111
  telemetryTracker.streamingEvent(AUTH_REJECTION);
115
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
112
+ pushEmitter.emit(PUSH_NON_RETRYABLE_ERROR);
116
113
  return;
117
114
  }
118
115
  // Handle other HTTP and network errors as recoverable errors
@@ -136,7 +133,7 @@ export function pushManagerFactory(params, pollingManager) {
136
133
  }
137
134
  // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
138
135
  function stopWorkers() {
139
- splitsUpdateWorker.stop();
136
+ definitionsUpdateWorker.stop();
140
137
  if (userKey)
141
138
  forOwn(clients, function (_a) {
142
139
  var worker = _a.worker;
@@ -152,7 +149,7 @@ export function pushManagerFactory(params, pollingManager) {
152
149
  connectPushRetryBackoff.reset();
153
150
  });
154
151
  /** Fallback to polling without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
155
- pushEmitter.on(PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
152
+ pushEmitter.on(PUSH_NON_RETRYABLE_ERROR, function handleNonRetryableError() {
156
153
  disabled = true;
157
154
  // Note: `stopWorkers` is been called twice, but it is not harmful
158
155
  disconnectPush();
@@ -178,9 +175,12 @@ export function pushManagerFactory(params, pollingManager) {
178
175
  connectPush();
179
176
  });
180
177
  /** Functions related to synchronization (Queues and Workers in the spec) */
181
- pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
182
- pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
183
- pushEmitter.on(RB_SEGMENT_UPDATE, splitsUpdateWorker.put);
178
+ // Some notification types are specific to the Feature flags or Configs SDKs. Their handlers are
179
+ // registered unconditionally, since the SDK only subscribes to the channels of its own entities.
180
+ pushEmitter.on(SPLIT_KILL, definitionsUpdateWorker.killDefinition);
181
+ pushEmitter.on(SPLIT_UPDATE, definitionsUpdateWorker.put);
182
+ pushEmitter.on(CONFIG_UPDATE, definitionsUpdateWorker.put);
183
+ pushEmitter.on(RB_SEGMENT_UPDATE, definitionsUpdateWorker.put);
184
184
  function handleMySegmentsUpdate(parsedData) {
185
185
  switch (parsedData.u) {
186
186
  case UpdateStrategy.BoundedFetchRequest: {
@@ -203,7 +203,7 @@ export function pushManagerFactory(params, pollingManager) {
203
203
  case UpdateStrategy.KeyList: {
204
204
  var keyList = void 0, added_1, removed_1;
205
205
  try {
206
- keyList = parseKeyList(parsedData.d, parsedData.c);
206
+ keyList = parseCompressedData(parsedData.d, parsedData.c);
207
207
  added_1 = new Set(keyList.a);
208
208
  removed_1 = new Set(keyList.r);
209
209
  }
@@ -282,9 +282,7 @@ export function pushManagerFactory(params, pollingManager) {
282
282
  },
283
283
  // [Only for client-side]
284
284
  add: function (userKey, mySegmentsSyncTask) {
285
- var hash = hashUserKey(userKey);
286
- if (!userKeyHashes[hash]) {
287
- userKeyHashes[hash] = userKey;
285
+ if (!clients[userKey]) {
288
286
  clients[userKey] = {
289
287
  hash64: hash64(userKey),
290
288
  worker: MySegmentsUpdateWorker(log, storage, mySegmentsSyncTask, telemetryTracker)
@@ -305,8 +303,6 @@ export function pushManagerFactory(params, pollingManager) {
305
303
  },
306
304
  // [Only for client-side]
307
305
  remove: function (userKey) {
308
- var hash = hashUserKey(userKey);
309
- delete userKeyHashes[hash];
310
306
  delete clients[userKey];
311
307
  }
312
308
  });
@@ -4,7 +4,7 @@ import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
4
4
  * Submitter that periodically posts tracked events
5
5
  */
6
6
  export function eventsSubmitterFactory(params) {
7
- var _a = params.settings, log = _a.log, eventsPushRate = _a.scheduler.eventsPushRate, eventsFirstPushWindow = _a.startup.eventsFirstPushWindow, postEventsBulk = params.splitApi.postEventsBulk, events = params.storage.events;
7
+ var _a = params.settings, log = _a.log, eventsPushRate = _a.scheduler.eventsPushRate, eventsFirstPushWindow = _a.startup.eventsFirstPushWindow, postEventsBulk = params.serviceApi.postEventsBulk, events = params.storage.events;
8
8
  // don't retry events.
9
9
  var submitter = submitterFactory(log, postEventsBulk, events, eventsPushRate);
10
10
  // Set a timer for the first push window of events.
@@ -25,7 +25,7 @@ var IMPRESSIONS_COUNT_RATE = 1800000; // 30 minutes
25
25
  * Submitter that periodically posts impression counts
26
26
  */
27
27
  export function impressionCountsSubmitterFactory(params) {
28
- var log = params.settings.log, postTestImpressionsCount = params.splitApi.postTestImpressionsCount, impressionCounts = params.storage.impressionCounts;
28
+ var log = params.settings.log, postTestImpressionsCount = params.serviceApi.postTestImpressionsCount, impressionCounts = params.storage.impressionCounts;
29
29
  // retry impressions counts only once.
30
30
  return submitterFactory(log, postTestImpressionsCount, impressionCounts, IMPRESSIONS_COUNT_RATE, fromImpressionCountsCollector, 1);
31
31
  }
@@ -11,7 +11,7 @@ export function fromImpressionsCollector(sendLabels, data) {
11
11
  dto.push({
12
12
  f: name,
13
13
  i: value.map(function (entry) {
14
- var keyImpression = {
14
+ return {
15
15
  k: entry.keyName,
16
16
  t: entry.treatment,
17
17
  m: entry.time,
@@ -19,9 +19,10 @@ export function fromImpressionsCollector(sendLabels, data) {
19
19
  r: sendLabels ? entry.label : undefined,
20
20
  b: entry.bucketingKey,
21
21
  pt: entry.pt,
22
- properties: entry.properties // Properties
22
+ properties: entry.properties,
23
+ // @TODO: add entityType to public SplitIO.ImpressionDTO type
24
+ et: entry.entityType, // Definition type
23
25
  };
24
- return keyImpression;
25
26
  })
26
27
  });
27
28
  });
@@ -31,7 +32,7 @@ export function fromImpressionsCollector(sendLabels, data) {
31
32
  * Submitter that periodically posts impressions data
32
33
  */
33
34
  export function impressionsSubmitterFactory(params) {
34
- var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.splitApi.postTestImpressionsBulk, impressions = params.storage.impressions;
35
+ var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.serviceApi.postTestImpressionsBulk, impressions = params.storage.impressions;
35
36
  // retry impressions only once.
36
37
  var syncTask = submitterFactory(log, postTestImpressionsBulk, impressions, impressionsRefreshRate, fromImpressionsCollector.bind(undefined, labelsEnabled), 1);
37
38
  // register impressions submitter to be executed when impressions cache is full
@@ -102,18 +102,17 @@ export function telemetrySubmitterFactory(params) {
102
102
  var telemetry = params.storage.telemetry, now = params.platform.now;
103
103
  if (!telemetry || !now)
104
104
  return; // No submitter created if telemetry cache is not defined
105
- var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, splitApi = params.splitApi, readiness = params.readiness, sdkReadinessManager = params.sdkReadinessManager;
105
+ var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, serviceApi = params.serviceApi, readiness = params.readiness;
106
106
  var stopTimer = timer(now);
107
- var submitter = firstPushWindowDecorator(submitterFactory(log, splitApi.postMetricsUsage, telemetry, telemetryRefreshRate, undefined, 0, true), telemetryRefreshRate);
107
+ var submitter = firstPushWindowDecorator(submitterFactory(log, serviceApi.postMetricsUsage, telemetry, telemetryRefreshRate, undefined, 0, true), telemetryRefreshRate);
108
108
  readiness.gate.once(SDK_READY_FROM_CACHE, function () {
109
109
  telemetry.recordTimeUntilReadyFromCache(stopTimer());
110
110
  });
111
- sdkReadinessManager.incInternalReadyCbCount();
112
111
  readiness.gate.once(SDK_READY, function () {
113
112
  telemetry.recordTimeUntilReady(stopTimer());
114
113
  // Post config data when the SDK is ready and if the telemetry submitter was started
115
114
  if (submitter.isRunning()) {
116
- var postMetricsConfigTask = submitterFactory(log, splitApi.postMetricsConfig, telemetryCacheConfigAdapter(telemetry, settings), 0, undefined, 0, true);
115
+ var postMetricsConfigTask = submitterFactory(log, serviceApi.postMetricsConfig, telemetryCacheConfigAdapter(telemetry, settings), 0, undefined, 0, true);
117
116
  postMetricsConfigTask.execute();
118
117
  }
119
118
  });
@@ -5,7 +5,7 @@ var UNIQUE_KEYS_RATE = 900000; // 15 minutes
5
5
  * Submitter that periodically posts impression counts
6
6
  */
7
7
  export function uniqueKeysSubmitterFactory(params) {
8
- var _a = params.settings, log = _a.log, key = _a.core.key, _b = params.splitApi, postUniqueKeysBulkCs = _b.postUniqueKeysBulkCs, postUniqueKeysBulkSs = _b.postUniqueKeysBulkSs, uniqueKeys = params.storage.uniqueKeys;
8
+ var _a = params.settings, log = _a.log, key = _a.core.key, _b = params.serviceApi, postUniqueKeysBulkCs = _b.postUniqueKeysBulkCs, postUniqueKeysBulkSs = _b.postUniqueKeysBulkSs, uniqueKeys = params.storage.uniqueKeys;
9
9
  var isClientSide = key !== undefined;
10
10
  var postUniqueKeysBulk = isClientSide ? postUniqueKeysBulkCs : postUniqueKeysBulkSs;
11
11
  var syncTask = submitterFactory(log, postUniqueKeysBulk, uniqueKeys, UNIQUE_KEYS_RATE);
@@ -3,8 +3,8 @@ import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
3
3
  import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
4
4
  import { isConsentGranted } from '../consent';
5
5
  import { POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
6
- import { SDK_SPLITS_CACHE_LOADED } from '../readiness/constants';
7
- import { usesSegmentsSync } from '../storages/AbstractSplitsCacheSync';
6
+ import { SDK_DEFINITIONS_CACHE_LOADED } from '../readiness/constants';
7
+ import { usesSegmentsSync } from '../storages/AbstractDefinitionsCacheSync';
8
8
  /**
9
9
  * Online SyncManager factory.
10
10
  * Can be used for server-side API, and client-side API with or without multiple clients.
@@ -26,7 +26,7 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
26
26
  pushManagerFactory(params, pollingManager) :
27
27
  undefined;
28
28
  /** Submitter Manager */
29
- // It is not inyected as push and polling managers, because at the moment it is required
29
+ // It is not injected as push and polling managers, because at the moment it is required
30
30
  var submitterManager = submitterManagerFactory(params);
31
31
  /** Sync Manager logic */
32
32
  function startPolling() {
@@ -74,7 +74,7 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
74
74
  if (startFirstTime) {
75
75
  // Emits SDK_READY_FROM_CACHE
76
76
  if (!cacheMetadata.initialCacheLoad) {
77
- readiness.splits.emit(SDK_SPLITS_CACHE_LOADED, cacheMetadata);
77
+ readiness.definitions.emit(SDK_DEFINITIONS_CACHE_LOADED, cacheMetadata);
78
78
  }
79
79
  }
80
80
  // start syncing splits and segments
@@ -1,6 +1,7 @@
1
1
  var Backoff = /** @class */ (function () {
2
2
  /**
3
- * Schedule function calls with exponential backoff
3
+ * Schedule function calls with exponential backoff.
4
+ * @param cb - The function to call. Must return a promise if used with `scheduleCallAsync`.
4
5
  */
5
6
  function Backoff(cb, baseMillis, maxMillis) {
6
7
  this.baseMillis = Backoff.__TEST__BASE_MILLIS || baseMillis || Backoff.DEFAULT_BASE_MILLIS;
@@ -17,19 +18,50 @@ var Backoff = /** @class */ (function () {
17
18
  var delayInMillis = Math.min(this.baseMillis * Math.pow(2, this.attempts), this.maxMillis);
18
19
  if (this.timeoutID)
19
20
  clearTimeout(this.timeoutID);
21
+ this.attempts++;
20
22
  this.timeoutID = setTimeout(function () {
21
23
  _this.timeoutID = undefined;
22
24
  _this.cb();
23
25
  }, delayInMillis);
24
- this.attempts++;
25
26
  return delayInMillis;
26
27
  };
27
- Backoff.prototype.reset = function () {
28
+ /**
29
+ * Schedule a delayed call to `cb`
30
+ * @returns a promise that resolves/rejects with the result of the `cb` function, which must return a promise.
31
+ */
32
+ Backoff.prototype.scheduleCallAsync = function () {
33
+ var _this = this;
34
+ var delayInMillis = Math.min(this.baseMillis * Math.pow(2, this.attempts), this.maxMillis);
35
+ if (this.timeoutID)
36
+ clearTimeout(this.timeoutID);
37
+ this.attempts++;
38
+ return new Promise(function (resolve, reject) {
39
+ _this.pending = { resolve: resolve, reject: reject };
40
+ _this.timeoutID = setTimeout(function () {
41
+ _this.timeoutID = undefined;
42
+ _this.pending = undefined;
43
+ _this.cb().then(resolve, reject);
44
+ }, delayInMillis);
45
+ });
46
+ };
47
+ /**
48
+ * Reset the backoff attempts, canceling any scheduled `cb` call. If a `scheduleCallAsync` call is pending
49
+ * and the caller wants to settle it immediately instead of waiting for `cb` to be invoked, pass `settle`:
50
+ * `{ value }` to resolve, or `{ error }` to reject.
51
+ */
52
+ Backoff.prototype.reset = function (settle) {
28
53
  this.attempts = 0;
29
54
  if (this.timeoutID) {
30
55
  clearTimeout(this.timeoutID);
31
56
  this.timeoutID = undefined;
32
57
  }
58
+ if (settle && this.pending) {
59
+ if ('value' in settle)
60
+ this.pending.resolve(settle.value);
61
+ else
62
+ this.pending.reject(settle.error);
63
+ this.pending = undefined;
64
+ }
33
65
  };
34
66
  Backoff.DEFAULT_BASE_MILLIS = 1000; // 1 second
35
67
  Backoff.DEFAULT_MAX_MILLIS = 1800000; // 30 minutes