@splitsoftware/splitio-commons 0.1.1-canary.6 → 0.1.1-rc.18

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 (269) hide show
  1. package/cjs/evaluator/matchers/matcherTypes.js +4 -4
  2. package/cjs/evaluator/matchersTransform/index.js +11 -11
  3. package/cjs/evaluator/value/sanitize.js +6 -6
  4. package/cjs/listeners/browser.js +5 -2
  5. package/cjs/listeners/node.js +9 -2
  6. package/cjs/logger/constants.js +3 -1
  7. package/cjs/logger/messages/error.js +3 -2
  8. package/cjs/logger/messages/info.js +2 -2
  9. package/cjs/logger/messages/warn.js +2 -1
  10. package/cjs/readiness/readinessManager.js +10 -7
  11. package/cjs/sdkFactory/index.js +1 -1
  12. package/cjs/services/splitApi.js +9 -1
  13. package/cjs/services/splitHttpClient.js +5 -4
  14. package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
  15. package/cjs/storages/inLocalStorage/index.js +5 -2
  16. package/cjs/storages/inMemory/InMemoryStorage.js +2 -0
  17. package/cjs/storages/inMemory/InMemoryStorageCS.js +2 -0
  18. package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -2
  19. package/cjs/storages/inRedis/index.js +5 -2
  20. package/cjs/storages/pluggable/SplitsCachePluggable.js +6 -2
  21. package/cjs/storages/pluggable/inMemoryWrapper.js +6 -7
  22. package/cjs/storages/pluggable/index.js +5 -2
  23. package/cjs/storages/pluggable/wrapperAdapter.js +0 -1
  24. package/cjs/sync/offline/splitsParser/splitsParserFromFile.js +92 -89
  25. package/cjs/sync/offline/splitsParser/splitsParserFromSettings.js +45 -42
  26. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +14 -4
  27. package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +0 -8
  28. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +30 -10
  29. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +2 -4
  30. package/cjs/sync/streaming/SSEClient/index.js +38 -20
  31. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  32. package/cjs/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  33. package/cjs/sync/streaming/SSEHandler/index.js +8 -9
  34. package/cjs/sync/streaming/SSEHandler/types.js +14 -0
  35. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  36. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  37. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  38. package/cjs/sync/streaming/constants.js +3 -1
  39. package/cjs/sync/streaming/mySegmentsV2utils.js +75 -0
  40. package/cjs/sync/streaming/pushManager.js +148 -40
  41. package/cjs/sync/submitters/metricsSyncTask.js +1 -1
  42. package/cjs/sync/submitters/submitterSyncTask.js +2 -2
  43. package/cjs/sync/syncManagerFromFile.js +15 -0
  44. package/cjs/sync/syncManagerFromObject.js +14 -0
  45. package/cjs/sync/syncManagerOffline.js +3 -3
  46. package/cjs/sync/syncManagerOnline.js +18 -5
  47. package/cjs/sync/syncTask.js +1 -1
  48. package/cjs/trackers/impressionObserver/ImpressionObserver.js +0 -2
  49. package/cjs/trackers/impressionObserver/buildKey.js +3 -9
  50. package/cjs/trackers/impressionObserver/impressionObserverCS.js +2 -2
  51. package/cjs/trackers/impressionObserver/impressionObserverSS.js +3 -3
  52. package/cjs/utils/constants/index.js +4 -1
  53. package/cjs/utils/decompress/index.js +427 -0
  54. package/cjs/utils/murmur3/{commons.js → common.js} +2 -6
  55. package/cjs/utils/murmur3/murmur3.js +11 -12
  56. package/cjs/utils/murmur3/murmur3_128.js +7 -142
  57. package/cjs/utils/murmur3/murmur3_128_x86.js +154 -0
  58. package/cjs/utils/murmur3/murmur3_64.js +36 -0
  59. package/cjs/utils/murmur3/utfx.js +100 -106
  60. package/cjs/utils/promise/wrapper.js +14 -11
  61. package/cjs/utils/settingsValidation/index.js +5 -2
  62. package/cjs/utils/settingsValidation/localhost/index.js +20 -0
  63. package/cjs/utils/settingsValidation/splitFilters.js +0 -1
  64. package/cjs/utils/settingsValidation/storage/storageCS.js +18 -8
  65. package/cjs/utils/settingsValidation/url.js +1 -1
  66. package/esm/evaluator/matchers/matcherTypes.js +2 -2
  67. package/esm/evaluator/matchersTransform/index.js +12 -12
  68. package/esm/evaluator/value/sanitize.js +7 -7
  69. package/esm/listeners/browser.js +5 -2
  70. package/esm/listeners/node.js +9 -2
  71. package/esm/logger/constants.js +2 -0
  72. package/esm/logger/messages/error.js +3 -2
  73. package/esm/logger/messages/info.js +2 -2
  74. package/esm/logger/messages/warn.js +2 -1
  75. package/esm/readiness/readinessManager.js +10 -7
  76. package/esm/sdkFactory/index.js +1 -1
  77. package/esm/services/splitApi.js +9 -1
  78. package/esm/services/splitHttpClient.js +5 -4
  79. package/esm/storages/AbstractSplitsCacheSync.js +1 -1
  80. package/esm/storages/inLocalStorage/index.js +5 -2
  81. package/esm/storages/inMemory/InMemoryStorage.js +2 -0
  82. package/esm/storages/inMemory/InMemoryStorageCS.js +2 -0
  83. package/esm/storages/inRedis/SplitsCacheInRedis.js +6 -2
  84. package/esm/storages/inRedis/index.js +5 -2
  85. package/esm/storages/pluggable/SplitsCachePluggable.js +6 -2
  86. package/esm/storages/pluggable/inMemoryWrapper.js +6 -7
  87. package/esm/storages/pluggable/index.js +5 -2
  88. package/esm/storages/pluggable/wrapperAdapter.js +0 -1
  89. package/esm/sync/offline/splitsParser/splitsParserFromFile.js +90 -88
  90. package/esm/sync/offline/splitsParser/splitsParserFromSettings.js +43 -41
  91. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +15 -5
  92. package/esm/sync/polling/fetchers/segmentChangesFetcher.js +0 -8
  93. package/esm/sync/polling/updaters/mySegmentsUpdater.js +30 -10
  94. package/esm/sync/polling/updaters/segmentChangesUpdater.js +2 -4
  95. package/esm/sync/streaming/SSEClient/index.js +38 -20
  96. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  97. package/esm/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  98. package/esm/sync/streaming/SSEHandler/index.js +9 -10
  99. package/esm/sync/streaming/SSEHandler/types.js +13 -1
  100. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  101. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  102. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  103. package/esm/sync/streaming/constants.js +2 -0
  104. package/esm/sync/streaming/mySegmentsV2utils.js +69 -0
  105. package/esm/sync/streaming/pushManager.js +150 -42
  106. package/esm/sync/submitters/metricsSyncTask.js +1 -1
  107. package/esm/sync/submitters/submitterSyncTask.js +2 -2
  108. package/esm/sync/syncManagerFromFile.js +11 -0
  109. package/esm/sync/syncManagerFromObject.js +10 -0
  110. package/esm/sync/syncManagerOffline.js +3 -3
  111. package/esm/sync/syncManagerOnline.js +18 -5
  112. package/esm/sync/syncTask.js +1 -1
  113. package/esm/trackers/impressionObserver/ImpressionObserver.js +0 -2
  114. package/esm/trackers/impressionObserver/buildKey.js +2 -9
  115. package/esm/trackers/impressionObserver/impressionObserverCS.js +2 -2
  116. package/esm/trackers/impressionObserver/impressionObserverSS.js +3 -3
  117. package/esm/utils/constants/index.js +3 -0
  118. package/esm/utils/decompress/index.js +424 -0
  119. package/esm/utils/murmur3/{commons.js → common.js} +1 -4
  120. package/esm/utils/murmur3/murmur3.js +1 -2
  121. package/esm/utils/murmur3/murmur3_128.js +7 -142
  122. package/esm/utils/murmur3/murmur3_128_x86.js +150 -0
  123. package/esm/utils/murmur3/murmur3_64.js +32 -0
  124. package/esm/utils/murmur3/utfx.js +96 -106
  125. package/esm/utils/promise/wrapper.js +14 -11
  126. package/esm/utils/settingsValidation/index.js +5 -2
  127. package/esm/utils/settingsValidation/localhost/index.js +16 -0
  128. package/esm/utils/settingsValidation/splitFilters.js +0 -1
  129. package/esm/utils/settingsValidation/storage/storageCS.js +16 -7
  130. package/esm/utils/settingsValidation/url.js +1 -1
  131. package/package.json +5 -5
  132. package/src/evaluator/matchers/matcherTypes.ts +2 -2
  133. package/src/evaluator/matchersTransform/index.ts +12 -12
  134. package/src/evaluator/value/sanitize.ts +7 -7
  135. package/src/listeners/browser.ts +5 -2
  136. package/src/listeners/node.ts +14 -2
  137. package/src/logger/constants.ts +2 -0
  138. package/src/logger/messages/error.ts +3 -2
  139. package/src/logger/messages/info.ts +2 -2
  140. package/src/logger/messages/warn.ts +3 -1
  141. package/src/readiness/readinessManager.ts +9 -7
  142. package/src/sdkFactory/index.ts +1 -1
  143. package/src/sdkFactory/types.ts +4 -5
  144. package/src/services/splitApi.ts +12 -3
  145. package/src/services/splitHttpClient.ts +6 -5
  146. package/src/services/types.ts +7 -3
  147. package/src/storages/AbstractSplitsCacheSync.ts +1 -1
  148. package/src/storages/inLocalStorage/index.ts +8 -4
  149. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  150. package/src/storages/inMemory/InMemoryStorageCS.ts +3 -0
  151. package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -1
  152. package/src/storages/inRedis/index.ts +8 -4
  153. package/src/storages/pluggable/SegmentsCachePluggable.ts +1 -1
  154. package/src/storages/pluggable/SplitsCachePluggable.ts +3 -1
  155. package/src/storages/pluggable/inMemoryWrapper.ts +6 -7
  156. package/src/storages/pluggable/index.ts +8 -4
  157. package/src/storages/pluggable/wrapperAdapter.ts +0 -1
  158. package/src/storages/types.ts +18 -15
  159. package/src/sync/offline/splitsParser/splitsParserFromFile.ts +110 -105
  160. package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +45 -41
  161. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +15 -5
  162. package/src/sync/polling/fetchers/segmentChangesFetcher.ts +0 -7
  163. package/src/sync/polling/types.ts +2 -1
  164. package/src/sync/polling/updaters/mySegmentsUpdater.ts +28 -10
  165. package/src/sync/polling/updaters/segmentChangesUpdater.ts +2 -3
  166. package/src/sync/streaming/AuthClient/types.ts +3 -0
  167. package/src/sync/streaming/SSEClient/index.ts +43 -23
  168. package/src/sync/streaming/SSEClient/types.ts +0 -1
  169. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +8 -0
  170. package/src/sync/streaming/SSEHandler/NotificationParser.ts +4 -2
  171. package/src/sync/streaming/SSEHandler/index.ts +11 -20
  172. package/src/sync/streaming/SSEHandler/types.ts +37 -3
  173. package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +7 -6
  174. package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +2 -1
  175. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +4 -3
  176. package/src/sync/streaming/UpdateWorkers/types.ts +1 -1
  177. package/src/sync/streaming/constants.ts +2 -0
  178. package/src/sync/streaming/mySegmentsV2utils.ts +77 -0
  179. package/src/sync/streaming/pushManager.ts +145 -42
  180. package/src/sync/streaming/types.ts +14 -22
  181. package/src/sync/submitters/metricsSyncTask.ts +1 -1
  182. package/src/sync/submitters/submitterSyncTask.ts +2 -1
  183. package/src/sync/syncManagerFromFile.ts +13 -0
  184. package/src/sync/syncManagerFromObject.ts +12 -0
  185. package/src/sync/syncManagerOffline.ts +3 -3
  186. package/src/sync/syncManagerOnline.ts +19 -5
  187. package/src/sync/syncTask.ts +1 -1
  188. package/src/sync/types.ts +3 -1
  189. package/src/trackers/impressionObserver/ImpressionObserver.ts +4 -6
  190. package/src/trackers/impressionObserver/buildKey.ts +2 -16
  191. package/src/trackers/impressionObserver/impressionObserverCS.ts +2 -2
  192. package/src/trackers/impressionObserver/impressionObserverSS.ts +3 -3
  193. package/src/types.ts +16 -2
  194. package/src/utils/constants/index.ts +6 -1
  195. package/src/utils/decompress/index.ts +429 -0
  196. package/src/utils/lang/index.ts +1 -1
  197. package/src/utils/murmur3/{commons.ts → common.ts} +1 -5
  198. package/src/utils/murmur3/murmur3.ts +5 -5
  199. package/src/utils/murmur3/murmur3_128.ts +7 -180
  200. package/src/utils/murmur3/murmur3_128_x86.ts +188 -0
  201. package/src/utils/murmur3/murmur3_64.ts +36 -0
  202. package/src/utils/murmur3/utfx.ts +92 -110
  203. package/src/utils/promise/wrapper.ts +12 -9
  204. package/src/utils/settingsValidation/index.ts +8 -4
  205. package/src/utils/settingsValidation/localhost/index.ts +19 -0
  206. package/src/utils/settingsValidation/splitFilters.ts +0 -1
  207. package/src/utils/settingsValidation/storage/storageCS.ts +21 -8
  208. package/src/utils/settingsValidation/types.ts +2 -11
  209. package/src/utils/settingsValidation/url.ts +1 -1
  210. package/types/evaluator/matchers/matcherTypes.d.ts +2 -2
  211. package/types/listeners/browser.d.ts +3 -3
  212. package/types/listeners/node.d.ts +3 -2
  213. package/types/logger/constants.d.ts +2 -0
  214. package/types/sdkFactory/types.d.ts +4 -5
  215. package/types/services/types.d.ts +4 -0
  216. package/types/storages/inLocalStorage/index.d.ts +2 -2
  217. package/types/storages/inMemory/InMemoryStorage.d.ts +3 -0
  218. package/types/storages/inMemory/InMemoryStorageCS.d.ts +3 -0
  219. package/types/storages/inRedis/index.d.ts +2 -2
  220. package/types/storages/pluggable/index.d.ts +2 -2
  221. package/types/storages/types.d.ts +15 -15
  222. package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -7
  223. package/types/sync/offline/splitsParser/splitsParserFromSettings.d.ts +1 -5
  224. package/types/sync/polling/types.d.ts +2 -1
  225. package/types/sync/streaming/AuthClient/indexV1.d.ts +12 -0
  226. package/types/sync/streaming/AuthClient/indexV2.d.ts +8 -0
  227. package/types/sync/streaming/AuthClient/types.d.ts +2 -0
  228. package/types/sync/streaming/SSEClient/index.d.ts +9 -12
  229. package/types/sync/streaming/SSEClient/types.d.ts +0 -1
  230. package/types/sync/streaming/SSEHandler/NotificationParser.d.ts +3 -2
  231. package/types/sync/streaming/SSEHandler/types.d.ts +30 -2
  232. package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +4 -3
  233. package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +2 -1
  234. package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +3 -2
  235. package/types/sync/streaming/UpdateWorkers/types.d.ts +1 -1
  236. package/types/sync/streaming/constants.d.ts +3 -1
  237. package/types/sync/streaming/mySegmentsV2utils.d.ts +27 -0
  238. package/types/sync/streaming/pushManagerNoUsers.d.ts +13 -0
  239. package/types/sync/streaming/types.d.ts +9 -5
  240. package/types/sync/submitters/submitterSyncTask.d.ts +1 -1
  241. package/types/sync/syncManagerFromFile.d.ts +2 -0
  242. package/types/sync/syncManagerFromObject.d.ts +2 -0
  243. package/types/sync/syncManagerOffline.d.ts +1 -1
  244. package/types/sync/syncTask.d.ts +1 -1
  245. package/types/sync/types.d.ts +2 -0
  246. package/types/trackers/impressionObserver/ImpressionObserver.d.ts +2 -2
  247. package/types/trackers/impressionObserver/buildKey.d.ts +1 -1
  248. package/types/trackers/impressionObserver/impressionObserverCS.d.ts +2 -2
  249. package/types/trackers/impressionObserver/impressionObserverSS.d.ts +2 -2
  250. package/types/types.d.ts +16 -2
  251. package/types/utils/constants/index.d.ts +5 -1
  252. package/types/utils/decompress/index.d.ts +16 -0
  253. package/types/utils/lang/index.d.ts +1 -1
  254. package/types/utils/murmur3/common.d.ts +12 -0
  255. package/types/utils/murmur3/murmur3.d.ts +2 -2
  256. package/types/utils/murmur3/murmur3_128.d.ts +5 -0
  257. package/types/utils/murmur3/murmur3_128_x86.d.ts +7 -0
  258. package/types/utils/murmur3/murmur3_64.d.ts +10 -0
  259. package/types/utils/murmur3/utfx.d.ts +24 -6
  260. package/types/utils/settingsValidation/index.d.ts +3 -2
  261. package/types/utils/settingsValidation/localhost/index.d.ts +9 -0
  262. package/types/utils/settingsValidation/storage/storageCS.d.ts +7 -1
  263. package/types/utils/settingsValidation/types.d.ts +2 -10
  264. package/cjs/sync/streaming/pushManagerCS.js +0 -178
  265. package/cjs/sync/streaming/pushManagerSS.js +0 -128
  266. package/esm/sync/streaming/pushManagerCS.js +0 -174
  267. package/esm/sync/streaming/pushManagerSS.js +0 -124
  268. package/src/sync/streaming/pushManagerCS.ts +0 -237
  269. package/src/sync/streaming/pushManagerSS.ts +0 -177
@@ -10,7 +10,7 @@ var MySegmentsUpdateWorker = /** @class */ (function () {
10
10
  this.mySegmentsSyncTask = mySegmentsSyncTask;
11
11
  this.maxChangeNumber = 0; // keeps the maximum changeNumber among queued events
12
12
  this.handleNewEvent = false;
13
- this.segmentList = undefined; // keeps the segmentList (if included in payload) from the queued event with maximum changeNumber
13
+ this.segmentsData = undefined; // keeps the segmentsData (if included in notification payload) from the queued event with maximum changeNumber
14
14
  this.currentChangeNumber = -1; // @TODO: remove once `/mySegments` endpoint provides the changeNumber
15
15
  this.put = this.put.bind(this);
16
16
  this.__handleMySegmentsUpdateCall = this.__handleMySegmentsUpdateCall.bind(this);
@@ -24,7 +24,7 @@ var MySegmentsUpdateWorker = /** @class */ (function () {
24
24
  this.handleNewEvent = false;
25
25
  var currentMaxChangeNumber_1 = this.maxChangeNumber;
26
26
  // fetch mySegments revalidating data if cached
27
- this.mySegmentsSyncTask.execute(this.segmentList, true).then(function (result) {
27
+ this.mySegmentsSyncTask.execute(this.segmentsData, true).then(function (result) {
28
28
  if (result !== false) // Unlike `Splits|SegmentsUpdateWorker`, we cannot use `mySegmentsCache.getChangeNumber` since `/mySegments` endpoint doesn't provide this value.
29
29
  _this.currentChangeNumber = Math.max(_this.currentChangeNumber, currentMaxChangeNumber_1); // use `currentMaxChangeNumber`, in case that `this.maxChangeNumber` was updated during fetch.
30
30
  if (_this.handleNewEvent) {
@@ -40,15 +40,15 @@ var MySegmentsUpdateWorker = /** @class */ (function () {
40
40
  * Invoked by NotificationProcessor on MY_SEGMENTS_UPDATE event
41
41
  *
42
42
  * @param {number} changeNumber change number of the MY_SEGMENTS_UPDATE notification
43
- * @param {string[] | undefined} segmentList might be undefined
43
+ * @param {SegmentsData | undefined} segmentsData might be undefined
44
44
  */
45
- MySegmentsUpdateWorker.prototype.put = function (changeNumber, segmentList) {
45
+ MySegmentsUpdateWorker.prototype.put = function (changeNumber, segmentsData) {
46
46
  if (changeNumber <= this.currentChangeNumber || changeNumber <= this.maxChangeNumber)
47
47
  return;
48
48
  this.maxChangeNumber = changeNumber;
49
49
  this.handleNewEvent = true;
50
50
  this.backoff.reset();
51
- this.segmentList = segmentList;
51
+ this.segmentsData = segmentsData;
52
52
  if (this.mySegmentsSyncTask.isExecuting())
53
53
  return;
54
54
  this.__handleMySegmentsUpdateCall();
@@ -54,7 +54,8 @@ var SegmentsUpdateWorker = /** @class */ (function () {
54
54
  * @param {number} changeNumber change number of the SEGMENT_UPDATE notification
55
55
  * @param {string} segmentName segment name of the SEGMENT_UPDATE notification
56
56
  */
57
- SegmentsUpdateWorker.prototype.put = function (changeNumber, segmentName) {
57
+ SegmentsUpdateWorker.prototype.put = function (_a) {
58
+ var changeNumber = _a.changeNumber, segmentName = _a.segmentName;
58
59
  var currentChangeNumber = this.segmentsCache.getChangeNumber(segmentName);
59
60
  if (changeNumber <= currentChangeNumber || changeNumber <= this.maxChangeNumbers[segmentName])
60
61
  return;
@@ -46,7 +46,8 @@ var SplitsUpdateWorker = /** @class */ (function () {
46
46
  *
47
47
  * @param {number} changeNumber change number of the SPLIT_UPDATE notification
48
48
  */
49
- SplitsUpdateWorker.prototype.put = function (changeNumber) {
49
+ SplitsUpdateWorker.prototype.put = function (_a) {
50
+ var changeNumber = _a.changeNumber;
50
51
  var currentChangeNumber = this.splitsCache.getChangeNumber();
51
52
  if (changeNumber <= currentChangeNumber || changeNumber <= this.maxChangeNumber)
52
53
  return;
@@ -64,14 +65,15 @@ var SplitsUpdateWorker = /** @class */ (function () {
64
65
  * @param {string} splitName name of split to kill
65
66
  * @param {string} defaultTreatment default treatment value
66
67
  */
67
- SplitsUpdateWorker.prototype.killSplit = function (changeNumber, splitName, defaultTreatment) {
68
+ SplitsUpdateWorker.prototype.killSplit = function (_a) {
69
+ var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment;
68
70
  // @TODO handle retry due to errors in storage, once we allow the definition of custom async storages
69
71
  if (this.splitsCache.killLocally(splitName, defaultTreatment, changeNumber)) {
70
72
  // trigger an SDK_UPDATE if Split was killed locally
71
73
  this.splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, true);
72
74
  }
73
75
  // queues the SplitChanges fetch (only if changeNumber is newer)
74
- this.put(changeNumber);
76
+ this.put({ changeNumber: changeNumber });
75
77
  };
76
78
  return SplitsUpdateWorker;
77
79
  }());
@@ -23,6 +23,7 @@ export var PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
23
23
  export var PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
24
24
  // Update-type push notifications, handled by NotificationProcessor
25
25
  export var MY_SEGMENTS_UPDATE = 'MY_SEGMENTS_UPDATE';
26
+ export var MY_SEGMENTS_UPDATE_V2 = 'MY_SEGMENTS_UPDATE_V2';
26
27
  export var SEGMENT_UPDATE = 'SEGMENT_UPDATE';
27
28
  export var SPLIT_KILL = 'SPLIT_KILL';
28
29
  export var SPLIT_UPDATE = 'SPLIT_UPDATE';
@@ -34,4 +35,5 @@ export var ControlType;
34
35
  ControlType["STREAMING_DISABLED"] = "STREAMING_DISABLED";
35
36
  ControlType["STREAMING_PAUSED"] = "STREAMING_PAUSED";
36
37
  ControlType["STREAMING_RESUMED"] = "STREAMING_RESUMED";
38
+ ControlType["STREAMING_RESET"] = "STREAMING_RESET";
37
39
  })(ControlType || (ControlType = {}));
@@ -0,0 +1,69 @@
1
+ import { algorithms } from '../../utils/decompress';
2
+ import { decodeFromBase64 } from '../../utils/base64';
3
+ var GZIP = 1;
4
+ var ZLIB = 2;
5
+ function Uint8ArrayToString(myUint8Arr) {
6
+ return String.fromCharCode.apply(null, myUint8Arr);
7
+ }
8
+ function StringToUint8Array(myString) {
9
+ var charCodes = myString.split('').map(function (e) { return e.charCodeAt(0); });
10
+ return new Uint8Array(charCodes);
11
+ }
12
+ /**
13
+ * Decode and decompress 'data' with 'compression' algorithm
14
+ *
15
+ * @param {string} data
16
+ * @param {number} compression 1 GZIP, 2 ZLIB
17
+ * @returns {Uint8Array}
18
+ * @throws if data string cannot be decoded, decompressed or the provided compression value is invalid (not 1 or 2)
19
+ */
20
+ function decompress(data, compression) {
21
+ var compressData = decodeFromBase64(data);
22
+ var binData = StringToUint8Array(compressData);
23
+ if (typeof algorithms === 'string')
24
+ throw new Error(algorithms);
25
+ if (compression === GZIP)
26
+ return algorithms.gunzipSync(binData);
27
+ if (compression === ZLIB)
28
+ return algorithms.unzlibSync(binData);
29
+ throw new Error("Invalid compression algorithm #" + compression);
30
+ }
31
+ /**
32
+ * Decode, decompress and parse the provided 'data' into a KeyList object
33
+ *
34
+ * @param {string} data
35
+ * @param {number} compression
36
+ * @returns {{a?: string[], r?: string[] }}
37
+ * @throws if data string cannot be decoded, decompressed or parsed
38
+ */
39
+ export function parseKeyList(data, compression) {
40
+ var binKeyList = decompress(data, compression);
41
+ var strKeyList = Uint8ArrayToString(binKeyList);
42
+ // replace numbers to strings, to avoid losing precision
43
+ return JSON.parse(strKeyList.replace(/\d+/g, '"$&"'));
44
+ }
45
+ /**
46
+ * Decode, decompress and parse the provided 'data' into a Bitmap object
47
+ *
48
+ * @param {string} data
49
+ * @param {number} compression
50
+ * @returns {Uint8Array}
51
+ * @throws if data string cannot be decoded or decompressed
52
+ */
53
+ export function parseBitmap(data, compression) {
54
+ return decompress(data, compression);
55
+ }
56
+ /**
57
+ * Check if the 'bitmap' bit at 'hash64hex' position is 1
58
+ *
59
+ * @param {Uint8Array} bitmap
60
+ * @param {string} hash64hex 16-chars string, representing a number in hexa
61
+ * @returns {boolean}
62
+ */
63
+ export function isInBitmap(bitmap, hash64hex) {
64
+ // using the lowest 32 bits as index, to avoid losing precision when converting to number
65
+ var index = parseInt(hash64hex.slice(8), 16) % (bitmap.length * 8);
66
+ var internal = Math.floor(index / 8);
67
+ var offset = index % 8;
68
+ return (bitmap[internal] & 1 << offset) > 0;
69
+ }
@@ -8,18 +8,26 @@ import { authenticateFactory, hashUserKey } from './AuthClient';
8
8
  import { forOwn } from '../../utils/lang';
9
9
  import SSEClient from './SSEClient';
10
10
  import { getMatching } from '../../utils/key';
11
- import { MY_SEGMENTS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP } from './constants';
12
- import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT } from '../../logger/constants';
11
+ import { MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
12
+ import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 } from '../../logger/constants';
13
+ import { UpdateStrategy } from './SSEHandler/types';
14
+ import { isInBitmap, parseBitmap, parseKeyList } from './mySegmentsV2utils';
15
+ import { _Set } from '../../utils/lang/sets';
16
+ import { hash64 } from '../../utils/murmur3/murmur3_64';
13
17
  /**
14
18
  * PushManager factory:
15
19
  * - for server-side if key is not provided in settings.
16
20
  * - for client-side, with support for multiple clients, if key is provided in settings
17
21
  */
18
22
  export default function pushManagerFactory(pollingManager, storage, readiness, fetchAuth, platform, settings) {
23
+ // `userKey` is the matching key of main client in client-side SDK.
24
+ // It can be used to check if running on client-side or server-side SDK.
25
+ var userKey = settings.core.key ? getMatching(settings.core.key) : undefined; //
19
26
  var log = settings.log;
20
27
  var sseClient;
21
28
  try {
22
- sseClient = new SSEClient(settings.urls.streaming, platform.getEventSource);
29
+ // `useHeaders` false for client-side, even if the platform EventSource supports headers (e.g., React Native).
30
+ sseClient = new SSEClient(settings, userKey ? false : true, platform.getEventSource);
23
31
  }
24
32
  catch (e) {
25
33
  log.warn(STREAMING_FALLBACK, [e]);
@@ -30,44 +38,58 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
30
38
  var pushEmitter = new platform.EventEmitter();
31
39
  var sseHandler = SSEHandlerFactory(log, pushEmitter);
32
40
  sseClient.setEventHandler(sseHandler);
41
+ // init workers
42
+ var segmentsUpdateWorker = userKey ? new MySegmentsUpdateWorker(pollingManager.segmentsSyncTask) : new SegmentsUpdateWorker(storage.segments, pollingManager.segmentsSyncTask);
43
+ // For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
44
+ var splitsUpdateWorker = new SplitsUpdateWorker(storage.splits, pollingManager.splitsSyncTask, readiness.splits, userKey ? undefined : pollingManager.segmentsSyncTask);
33
45
  // [Only for client-side] map of hashes to user keys, to dispatch MY_SEGMENTS_UPDATE events to the corresponding MySegmentsUpdateWorker
34
46
  var userKeyHashes = {};
35
- var userKey = settings.core.key ? getMatching(settings.core.key) : undefined; // matching key of main client
47
+ // [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
48
+ // Hash64 is used to process MY_SEGMENTS_UPDATE_V2 events and dispatch actions to the corresponding MySegmentsUpdateWorker.
49
+ var clients = {};
36
50
  if (userKey) {
37
51
  var hash = hashUserKey(userKey);
38
52
  userKeyHashes[hash] = userKey;
53
+ clients[userKey] = { hash64: hash64(userKey), worker: segmentsUpdateWorker };
39
54
  }
40
- // init workers
41
- var segmentsUpdateWorker = userKey ? new MySegmentsUpdateWorker(pollingManager.segmentsSyncTask) : new SegmentsUpdateWorker(storage.segments, pollingManager.segmentsSyncTask);
42
- // [Only for server-side] we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
43
- var splitsUpdateWorker = new SplitsUpdateWorker(storage.splits, pollingManager.splitsSyncTask, readiness.splits, userKey ? undefined : pollingManager.segmentsSyncTask);
44
- // [Only for client-side] map of user keys to their corresponding MySegmentsUpdateWorkers. It has a two-fold intention:
45
- // - stop workers all together when push is disconnected
46
- // - keep the current list of user keys to authenticate
47
- var workers = {};
48
- if (userKey)
49
- workers[userKey] = segmentsUpdateWorker;
50
55
  // [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
51
56
  var connectForNewClient = false;
52
- // flag that indicates if `disconnectPush` was called, either by the SyncManager (when the client is destroyed) or by a PUSH_NONRETRYABLE_ERROR error.
57
+ // 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.
53
58
  // It is used to halt the `connectPush` process if it was in progress.
54
59
  var disconnected;
60
+ // flag that indicates a PUSH_NONRETRYABLE_ERROR, condition with which starting pushManager again is ignored.
61
+ var disabled; // `disabled` implies `disconnected === true`
55
62
  /** PushManager functions related to initialization */
56
63
  var connectPushRetryBackoff = new Backoff(connectPush, settings.scheduler.pushRetryBackoffBase);
57
- var timeoutId;
58
- function scheduleTokenRefresh(issuedAt, expirationTime) {
59
- // clear scheduled token refresh if exists (needed when resuming PUSH)
60
- if (timeoutId)
61
- clearTimeout(timeoutId);
62
- // Set token refresh 10 minutes before expirationTime
63
- var delayInSeconds = expirationTime - issuedAt - SECONDS_BEFORE_EXPIRATION;
64
- log.info(STREAMING_REFRESH_TOKEN, [delayInSeconds]);
65
- timeoutId = setTimeout(connectPush, delayInSeconds * 1000);
64
+ var timeoutIdTokenRefresh;
65
+ var timeoutIdSseOpen;
66
+ function scheduleTokenRefreshAndSse(authData) {
67
+ // clear scheduled tasks if exist
68
+ if (timeoutIdTokenRefresh)
69
+ clearTimeout(timeoutIdTokenRefresh);
70
+ if (timeoutIdSseOpen)
71
+ clearTimeout(timeoutIdSseOpen);
72
+ // Set token refresh 10 minutes before `expirationTime - issuedAt`
73
+ var decodedToken = authData.decodedToken;
74
+ var refreshTokenDelay = decodedToken.exp - decodedToken.iat - SECONDS_BEFORE_EXPIRATION;
75
+ // Default connDelay of 60 secs
76
+ var connDelay = typeof authData.connDelay === 'number' && authData.connDelay >= 0 ? authData.connDelay : 60;
77
+ log.info(STREAMING_REFRESH_TOKEN, [refreshTokenDelay, connDelay]);
78
+ timeoutIdTokenRefresh = setTimeout(connectPush, refreshTokenDelay * 1000);
79
+ timeoutIdSseOpen = setTimeout(function () {
80
+ // halt if disconnected
81
+ if (disconnected)
82
+ return;
83
+ sseClient.open(authData);
84
+ }, connDelay * 1000);
66
85
  }
67
86
  function connectPush() {
87
+ // Guard condition in case `stop/disconnectPush` has been called (e.g., calling SDK destroy, or app signal close/background)
88
+ if (disconnected)
89
+ return;
90
+ log.info(STREAMING_CONNECTING, [disconnected === undefined ? '' : 'Re-']);
68
91
  disconnected = false;
69
- log.info(STREAMING_CONNECTING);
70
- var userKeys = userKey ? Object.keys(workers) : undefined;
92
+ var userKeys = userKey ? Object.keys(clients) : undefined;
71
93
  authenticate(userKeys).then(function (authData) {
72
94
  if (disconnected)
73
95
  return;
@@ -79,12 +101,10 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
79
101
  return;
80
102
  }
81
103
  // [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
82
- if (userKeys && userKeys.length < Object.keys(workers).length)
104
+ if (userKeys && userKeys.length < Object.keys(clients).length)
83
105
  return;
84
- // Connect to SSE and schedule refresh token
85
- var decodedToken = authData.decodedToken;
86
- sseClient.open(authData);
87
- scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
106
+ // Schedule SSE connection and refresh token
107
+ scheduleTokenRefreshAndSse(authData);
88
108
  }).catch(function (error) {
89
109
  if (disconnected)
90
110
  return;
@@ -100,11 +120,16 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
100
120
  }
101
121
  // close SSE connection and cancel scheduled tasks
102
122
  function disconnectPush() {
123
+ // Halt disconnecting, just to avoid redundant logs if called multiple times
124
+ if (disconnected)
125
+ return;
103
126
  disconnected = true;
104
- log.info(STREAMING_DISCONNECTING);
105
127
  sseClient.close();
106
- if (timeoutId)
107
- clearTimeout(timeoutId);
128
+ log.info(STREAMING_DISCONNECTING);
129
+ if (timeoutIdTokenRefresh)
130
+ clearTimeout(timeoutIdTokenRefresh);
131
+ if (timeoutIdSseOpen)
132
+ clearTimeout(timeoutIdSseOpen);
108
133
  connectPushRetryBackoff.reset();
109
134
  stopWorkers();
110
135
  }
@@ -112,15 +137,23 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
112
137
  function stopWorkers() {
113
138
  splitsUpdateWorker.backoff.reset();
114
139
  if (userKey)
115
- forOwn(workers, function (worker) { return worker.backoff.reset(); });
140
+ forOwn(clients, function (_a) {
141
+ var worker = _a.worker;
142
+ return worker.backoff.reset();
143
+ });
116
144
  else
117
145
  segmentsUpdateWorker.backoff.reset();
118
146
  }
119
147
  pushEmitter.on(PUSH_SUBSYSTEM_DOWN, stopWorkers);
120
- // restart backoff retry counter once push is connected
121
- pushEmitter.on(PUSH_SUBSYSTEM_UP, function () { connectPushRetryBackoff.reset(); });
148
+ // Only required when streaming connects after a PUSH_RETRYABLE_ERROR.
149
+ // Otherwise it is unnecessary (e.g, STREAMING_RESUMED).
150
+ pushEmitter.on(PUSH_SUBSYSTEM_UP, function () {
151
+ connectPushRetryBackoff.reset();
152
+ stopWorkers();
153
+ });
122
154
  /** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
123
155
  pushEmitter.on(PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
156
+ disabled = true;
124
157
  // Note: `stopWorkers` is been called twice, but it is not harmful
125
158
  disconnectPush();
126
159
  pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
@@ -134,6 +167,16 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
134
167
  log.info(STREAMING_RECONNECT, [delayInMillis / 1000]);
135
168
  pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
136
169
  });
170
+ /** STREAMING_RESET notification. Unlike a PUSH_RETRYABLE_ERROR, it doesn't emit PUSH_SUBSYSTEM_DOWN to fallback polling */
171
+ pushEmitter.on(ControlType.STREAMING_RESET, function handleStreamingReset() {
172
+ if (disconnected)
173
+ return; // should never happen
174
+ // Minimum required clean-up.
175
+ // `disconnectPush` cannot be called because it sets `disconnected` and thus `connectPush` will not execute
176
+ if (timeoutIdTokenRefresh)
177
+ clearTimeout(timeoutIdTokenRefresh);
178
+ connectPush();
179
+ });
137
180
  /** Functions related to synchronization (Queues and Workers in the spec) */
138
181
  pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
139
182
  pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
@@ -141,11 +184,72 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
141
184
  pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
142
185
  var userKeyHash = channel.split('_')[2];
143
186
  var userKey = userKeyHashes[userKeyHash];
144
- if (userKey && workers[userKey]) { // check context since it can be undefined if client has been destroyed
145
- var mySegmentsUpdateWorker = workers[userKey];
146
- mySegmentsUpdateWorker.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
187
+ if (userKey && clients[userKey]) { // check existence since it can be undefined if client has been destroyed
188
+ clients[userKey].worker.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
147
189
  }
148
190
  });
191
+ pushEmitter.on(MY_SEGMENTS_UPDATE_V2, function handleMySegmentsUpdate(parsedData) {
192
+ switch (parsedData.u) {
193
+ case UpdateStrategy.BoundedFetchRequest: {
194
+ var bitmap_1;
195
+ try {
196
+ bitmap_1 = parseBitmap(parsedData.d, parsedData.c);
197
+ }
198
+ catch (e) {
199
+ log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['BoundedFetchRequest', e]);
200
+ break;
201
+ }
202
+ forOwn(clients, function (_a) {
203
+ var hash64 = _a.hash64, worker = _a.worker;
204
+ if (isInBitmap(bitmap_1, hash64.hex)) {
205
+ worker.put(parsedData.changeNumber); // fetch mySegments
206
+ }
207
+ });
208
+ return;
209
+ }
210
+ case UpdateStrategy.KeyList: {
211
+ var keyList = void 0, added_1, removed_1;
212
+ try {
213
+ keyList = parseKeyList(parsedData.d, parsedData.c);
214
+ added_1 = new _Set(keyList.a);
215
+ removed_1 = new _Set(keyList.r);
216
+ }
217
+ catch (e) {
218
+ log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['KeyList', e]);
219
+ break;
220
+ }
221
+ forOwn(clients, function (_a) {
222
+ var hash64 = _a.hash64, worker = _a.worker;
223
+ var add = added_1.has(hash64.dec) ? true : removed_1.has(hash64.dec) ? false : undefined;
224
+ if (add !== undefined) {
225
+ worker.put(parsedData.changeNumber, {
226
+ name: parsedData.segmentName,
227
+ add: add
228
+ });
229
+ }
230
+ });
231
+ return;
232
+ }
233
+ case UpdateStrategy.SegmentRemoval:
234
+ if (!parsedData.segmentName) {
235
+ log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['SegmentRemoval', 'No segment name was provided']);
236
+ break;
237
+ }
238
+ forOwn(clients, function (_a) {
239
+ var worker = _a.worker;
240
+ return worker.put(parsedData.changeNumber, {
241
+ name: parsedData.segmentName,
242
+ add: false
243
+ });
244
+ });
245
+ return;
246
+ }
247
+ // `UpdateStrategy.UnboundedFetchRequest` and fallbacks of other cases
248
+ forOwn(clients, function (_a) {
249
+ var worker = _a.worker;
250
+ worker.put(parsedData.changeNumber);
251
+ });
252
+ });
149
253
  }
150
254
  else {
151
255
  pushEmitter.on(SEGMENT_UPDATE, segmentsUpdateWorker.put);
@@ -156,13 +260,16 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
156
260
  // Expose functionality for starting and stoping push mode:
157
261
  stop: disconnectPush,
158
262
  start: function () {
263
+ // Guard condition to avoid calling `connectPush` again if the `start` method is called multiple times or if push has been disabled.
264
+ if (disabled || disconnected === false)
265
+ return;
266
+ disconnected = false;
159
267
  // Run in next event-loop cycle for optimization on client-side: if multiple clients are created in the same cycle than the factory, only one authentication is performed.
160
268
  setTimeout(connectPush);
161
269
  },
162
270
  // [Only for client-side]
163
271
  add: function (userKey, mySegmentsSyncTask) {
164
- var mySegmentsUpdateWorker = new MySegmentsUpdateWorker(mySegmentsSyncTask);
165
- workers[userKey] = mySegmentsUpdateWorker;
272
+ clients[userKey] = { hash64: hash64(userKey), worker: new MySegmentsUpdateWorker(mySegmentsSyncTask) };
166
273
  var hash = hashUserKey(userKey);
167
274
  if (!userKeyHashes[hash]) {
168
275
  userKeyHashes[hash] = userKey;
@@ -182,6 +289,7 @@ export default function pushManagerFactory(pollingManager, storage, readiness, f
182
289
  remove: function (userKey) {
183
290
  var hash = hashUserKey(userKey);
184
291
  delete userKeyHashes[hash];
292
+ delete clients[userKey];
185
293
  }
186
294
  });
187
295
  }
@@ -22,5 +22,5 @@ export function countsSyncTaskFactory(log, postMetricsCounters, countsCache, met
22
22
  */
23
23
  export function latenciesSyncTaskFactory(log, postMetricsLatencies, latenciesCache, metricsRefreshRate, latencyTracker) {
24
24
  // don't retry metrics.
25
- return submitterSyncTaskFactory(log, postMetricsLatencies, latenciesCache, metricsRefreshRate, 'latency metrics', latencyTracker, fromCache('latencies'));
25
+ return submitterSyncTaskFactory(log, postMetricsLatencies, latenciesCache, metricsRefreshRate, 'latency metrics', latencyTracker, fromCache('latencies'), 0, true);
26
26
  }
@@ -3,7 +3,7 @@ import { SUBMITTERS_PUSH, SUBMITTERS_PUSH_FAILS, SUBMITTERS_PUSH_RETRY } from '.
3
3
  /**
4
4
  * Base function to create submitter sync tasks, such as ImpressionsSyncTask and EventsSyncTask
5
5
  */
6
- export function submitterSyncTaskFactory(log, postClient, sourceCache, postRate, dataName, latencyTracker, fromCacheToPayload, maxRetries) {
6
+ export function submitterSyncTaskFactory(log, postClient, sourceCache, postRate, dataName, latencyTracker, fromCacheToPayload, maxRetries, debugLogs) {
7
7
  if (maxRetries === void 0) { maxRetries = 0; }
8
8
  var retries = 0;
9
9
  function postData() {
@@ -11,7 +11,7 @@ export function submitterSyncTaskFactory(log, postClient, sourceCache, postRate,
11
11
  return Promise.resolve();
12
12
  var data = sourceCache.state();
13
13
  var dataCount = typeof data.length === 'number' ? data.length : '';
14
- log.info(SUBMITTERS_PUSH, [dataCount, dataName]);
14
+ log[debugLogs ? 'debug' : 'info'](SUBMITTERS_PUSH, [dataCount, dataName]);
15
15
  var latencyTrackerStop = latencyTracker && latencyTracker.start();
16
16
  var jsonPayload = JSON.stringify(fromCacheToPayload ? fromCacheToPayload(data) : data);
17
17
  if (!maxRetries)
@@ -0,0 +1,11 @@
1
+ import { splitsParserFromFileFactory } from './offline/splitsParser/splitsParserFromFile';
2
+ import { syncManagerOfflineFactory } from './syncManagerOffline';
3
+ import { LOCALHOST_MODE } from '../utils/constants';
4
+ // Factory of Localhost SyncManager based on yaml file.
5
+ // Requires Node 'fs' and 'path' APIs.
6
+ export function LocalhostFromFile() {
7
+ var localhost = syncManagerOfflineFactory(splitsParserFromFileFactory);
8
+ // @ts-ignore
9
+ localhost.type = LOCALHOST_MODE;
10
+ return localhost;
11
+ }
@@ -0,0 +1,10 @@
1
+ import { splitsParserFromSettingsFactory } from './offline/splitsParser/splitsParserFromSettings';
2
+ import { syncManagerOfflineFactory } from './syncManagerOffline';
3
+ import { LOCALHOST_MODE } from '../utils/constants';
4
+ // Factory of Localhost SyncManager based on JS object.
5
+ export function LocalhostFromObject() {
6
+ var localhost = syncManagerOfflineFactory(splitsParserFromSettingsFactory);
7
+ // @ts-ignore
8
+ localhost.type = LOCALHOST_MODE;
9
+ return localhost;
10
+ }
@@ -10,20 +10,20 @@ function flush() {
10
10
  *
11
11
  * @param splitsParser e.g., `splitsParserFromFile`, `splitsParserFromSettings`.
12
12
  */
13
- export function syncManagerOfflineFactory(splitsParser) {
13
+ export function syncManagerOfflineFactory(splitsParserFactory) {
14
14
  /**
15
15
  * SyncManager factory for modular SDK
16
16
  */
17
17
  return function (_a) {
18
18
  var settings = _a.settings, readiness = _a.readiness, storage = _a.storage;
19
- return objectAssign(fromObjectSyncTaskFactory(splitsParser, storage, readiness, settings), {
19
+ return objectAssign(fromObjectSyncTaskFactory(splitsParserFactory(), storage, readiness, settings), {
20
20
  // fake flush, that resolves immediately
21
21
  flush: flush,
22
22
  // [Only used for client-side]
23
23
  shared: function (matchingKey, readinessManager) {
24
24
  return {
25
25
  start: function () {
26
- // In LOCALHOST mode, shared clients are ready in the next event cycle than created
26
+ // In LOCALHOST mode, shared clients are ready in the next event-loop cycle than created
27
27
  // SDK_READY cannot be emitted directly because this will not update the readiness status
28
28
  setTimeout(function () {
29
29
  readinessManager.segments.emit(SDK_SEGMENTS_ARRIVED); // SDK_SPLITS_ARRIVED emitted by main SyncManager
@@ -53,15 +53,25 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
53
53
  // fetch splits and segments. There is no need to catch this promise (it is always resolved)
54
54
  pollingManager.syncAll();
55
55
  }
56
- var running = false;
56
+ if (pushManager) {
57
+ pushManager.on(PUSH_SUBSYSTEM_UP, stopPollingAndSyncAll);
58
+ pushManager.on(PUSH_SUBSYSTEM_DOWN, startPolling);
59
+ }
60
+ var running = false; // flag that indicates whether the syncManager has been started (true) or stopped (false)
61
+ var startFirstTime = true; // flag to distinguish calling the `start` method for the first time, to support pausing and resuming the synchronization
57
62
  return {
63
+ pushManager: pushManager,
64
+ /**
65
+ * Method used to start the syncManager for the first time, or resume it after being stopped.
66
+ */
58
67
  start: function () {
59
68
  // start syncing splits and segments
60
69
  if (pushManager) {
61
- pollingManager.syncAll();
62
- pushManager.on(PUSH_SUBSYSTEM_UP, stopPollingAndSyncAll);
63
- pushManager.on(PUSH_SUBSYSTEM_DOWN, startPolling);
64
- // Run in next event-loop cycle as in client-side SyncManager
70
+ // Doesn't call `syncAll` when the syncManager is resuming
71
+ if (startFirstTime) {
72
+ pollingManager.syncAll();
73
+ startFirstTime = false;
74
+ }
65
75
  pushManager.start();
66
76
  }
67
77
  else {
@@ -71,6 +81,9 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
71
81
  submitter && submitter.start();
72
82
  running = true;
73
83
  },
84
+ /**
85
+ * Method used to stop/pause the syncManager.
86
+ */
74
87
  stop: function () {
75
88
  // stop syncing
76
89
  if (pushManager)
@@ -1,6 +1,6 @@
1
1
  import { SYNC_TASK_EXECUTE, SYNC_TASK_START, SYNC_TASK_STOP } from '../logger/constants';
2
2
  /**
3
- * Creates a syncTask that handles the periodic execution of a givan task ("start" and "stop" methods).
3
+ * Creates a syncTask that handles the periodic execution of a given task ("start" and "stop" methods).
4
4
  * The task can be executed once calling the "execute" method.
5
5
  * NOTE: Multiple calls to "execute" are not queued. Use "isExecuting" method to handle synchronization.
6
6
  *
@@ -5,8 +5,6 @@ var ImpressionObserver = /** @class */ (function () {
5
5
  this.hasher = hasher;
6
6
  }
7
7
  ImpressionObserver.prototype.testAndSet = function (impression) {
8
- if (!impression)
9
- return;
10
8
  var hash = this.hasher(impression);
11
9
  var previous = this.cache.get(hash);
12
10
  this.cache.set(hash, impression.time);
@@ -1,10 +1,3 @@
1
- var UNKNOWN = 'UNKNOWN';
2
- function _unknownIfNull(s) {
3
- return s ? s : UNKNOWN;
4
- }
5
- function _zeroIfNull(l) {
6
- return l ? l : 0;
7
- }
8
- export default function buildKey(impression) {
9
- return _unknownIfNull(impression.keyName) + "\n :" + _unknownIfNull(impression.feature) + "\n :" + _unknownIfNull(impression.treatment) + "\n :" + _unknownIfNull(impression.label) + "\n :" + _zeroIfNull(impression.changeNumber);
1
+ export function buildKey(impression) {
2
+ return impression.keyName + ":" + impression.feature + ":" + impression.treatment + ":" + impression.label + ":" + impression.changeNumber;
10
3
  }
@@ -1,8 +1,8 @@
1
1
  import ImpressionObserver from './ImpressionObserver';
2
2
  import { hash } from '../../utils/murmur3/murmur3';
3
- import buildKey from './buildKey';
3
+ import { buildKey } from './buildKey';
4
4
  export function hashImpression32(impression) {
5
- return impression ? hash(buildKey(impression)).toString() : null;
5
+ return hash(buildKey(impression));
6
6
  }
7
7
  var LAST_SEEN_CACHE_SIZE = 500; // cache up to 500 impression hashes
8
8
  export function impressionObserverCSFactory() {
@@ -1,8 +1,8 @@
1
1
  import ImpressionObserver from './ImpressionObserver';
2
- import { hash128 } from '../../utils/murmur3/murmur3_128';
3
- import buildKey from './buildKey';
2
+ import { hash128 } from '../../utils/murmur3/murmur3_128_x86';
3
+ import { buildKey } from './buildKey';
4
4
  export function hashImpression128(impression) {
5
- return impression ? hash128(buildKey(impression)).toString() : null;
5
+ return hash128(buildKey(impression));
6
6
  }
7
7
  var LAST_SEEN_CACHE_SIZE = 500000; // cache up to 500k impression hashes
8
8
  export function impressionObserverSSFactory() {
@@ -20,3 +20,6 @@ export var PRODUCER_MODE = 'producer';
20
20
  export var CONSUMER_MODE = 'consumer';
21
21
  // Storage types
22
22
  export var STORAGE_MEMORY = 'MEMORY';
23
+ export var STORAGE_LOCALSTORAGE = 'LOCALSTORAGE';
24
+ export var STORAGE_REDIS = 'REDIS';
25
+ export var STORAGE_CUSTOM = 'CUSTOM';