@splitsoftware/splitio-commons 0.1.1-canary.9 → 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 (254) 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 +1 -2
  5. package/cjs/listeners/node.js +0 -3
  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 -4
  12. package/cjs/services/splitApi.js +1 -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/updaters/mySegmentsUpdater.js +30 -10
  28. package/cjs/sync/streaming/SSEClient/index.js +0 -11
  29. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  30. package/cjs/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  31. package/cjs/sync/streaming/SSEHandler/index.js +8 -9
  32. package/cjs/sync/streaming/SSEHandler/types.js +14 -0
  33. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  34. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  35. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  36. package/cjs/sync/streaming/constants.js +3 -1
  37. package/cjs/sync/streaming/mySegmentsV2utils.js +75 -0
  38. package/cjs/sync/streaming/pushManager.js +141 -40
  39. package/cjs/sync/submitters/metricsSyncTask.js +1 -1
  40. package/cjs/sync/submitters/submitterSyncTask.js +2 -2
  41. package/cjs/sync/syncManagerFromFile.js +15 -0
  42. package/cjs/sync/syncManagerFromObject.js +14 -0
  43. package/cjs/sync/syncManagerOffline.js +3 -3
  44. package/cjs/sync/syncManagerOnline.js +5 -3
  45. package/cjs/trackers/impressionObserver/ImpressionObserver.js +0 -2
  46. package/cjs/trackers/impressionObserver/buildKey.js +3 -9
  47. package/cjs/trackers/impressionObserver/impressionObserverCS.js +2 -2
  48. package/cjs/trackers/impressionObserver/impressionObserverSS.js +3 -3
  49. package/cjs/utils/constants/index.js +4 -1
  50. package/cjs/utils/decompress/index.js +427 -0
  51. package/cjs/utils/murmur3/{commons.js → common.js} +2 -6
  52. package/cjs/utils/murmur3/murmur3.js +11 -12
  53. package/cjs/utils/murmur3/murmur3_128.js +7 -142
  54. package/cjs/utils/murmur3/murmur3_128_x86.js +154 -0
  55. package/cjs/utils/murmur3/murmur3_64.js +36 -0
  56. package/cjs/utils/murmur3/utfx.js +100 -106
  57. package/cjs/utils/promise/wrapper.js +14 -11
  58. package/cjs/utils/settingsValidation/index.js +5 -2
  59. package/cjs/utils/settingsValidation/localhost/index.js +20 -0
  60. package/cjs/utils/settingsValidation/splitFilters.js +0 -1
  61. package/cjs/utils/settingsValidation/storage/storageCS.js +18 -8
  62. package/cjs/utils/settingsValidation/url.js +1 -1
  63. package/esm/evaluator/matchers/matcherTypes.js +2 -2
  64. package/esm/evaluator/matchersTransform/index.js +12 -12
  65. package/esm/evaluator/value/sanitize.js +7 -7
  66. package/esm/listeners/browser.js +1 -2
  67. package/esm/listeners/node.js +0 -3
  68. package/esm/logger/constants.js +2 -0
  69. package/esm/logger/messages/error.js +3 -2
  70. package/esm/logger/messages/info.js +2 -2
  71. package/esm/logger/messages/warn.js +2 -1
  72. package/esm/readiness/readinessManager.js +10 -7
  73. package/esm/sdkFactory/index.js +1 -4
  74. package/esm/services/splitApi.js +1 -1
  75. package/esm/services/splitHttpClient.js +5 -4
  76. package/esm/storages/AbstractSplitsCacheSync.js +1 -1
  77. package/esm/storages/inLocalStorage/index.js +5 -2
  78. package/esm/storages/inMemory/InMemoryStorage.js +2 -0
  79. package/esm/storages/inMemory/InMemoryStorageCS.js +2 -0
  80. package/esm/storages/inRedis/SplitsCacheInRedis.js +6 -2
  81. package/esm/storages/inRedis/index.js +5 -2
  82. package/esm/storages/pluggable/SplitsCachePluggable.js +6 -2
  83. package/esm/storages/pluggable/inMemoryWrapper.js +6 -7
  84. package/esm/storages/pluggable/index.js +5 -2
  85. package/esm/storages/pluggable/wrapperAdapter.js +0 -1
  86. package/esm/sync/offline/splitsParser/splitsParserFromFile.js +90 -88
  87. package/esm/sync/offline/splitsParser/splitsParserFromSettings.js +43 -41
  88. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +15 -5
  89. package/esm/sync/polling/updaters/mySegmentsUpdater.js +30 -10
  90. package/esm/sync/streaming/SSEClient/index.js +0 -11
  91. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +7 -0
  92. package/esm/sync/streaming/SSEHandler/NotificationParser.js +4 -1
  93. package/esm/sync/streaming/SSEHandler/index.js +9 -10
  94. package/esm/sync/streaming/SSEHandler/types.js +13 -1
  95. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +5 -5
  96. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -1
  97. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +5 -3
  98. package/esm/sync/streaming/constants.js +2 -0
  99. package/esm/sync/streaming/mySegmentsV2utils.js +69 -0
  100. package/esm/sync/streaming/pushManager.js +143 -42
  101. package/esm/sync/submitters/metricsSyncTask.js +1 -1
  102. package/esm/sync/submitters/submitterSyncTask.js +2 -2
  103. package/esm/sync/syncManagerFromFile.js +11 -0
  104. package/esm/sync/syncManagerFromObject.js +10 -0
  105. package/esm/sync/syncManagerOffline.js +3 -3
  106. package/esm/sync/syncManagerOnline.js +5 -3
  107. package/esm/trackers/impressionObserver/ImpressionObserver.js +0 -2
  108. package/esm/trackers/impressionObserver/buildKey.js +2 -9
  109. package/esm/trackers/impressionObserver/impressionObserverCS.js +2 -2
  110. package/esm/trackers/impressionObserver/impressionObserverSS.js +3 -3
  111. package/esm/utils/constants/index.js +3 -0
  112. package/esm/utils/decompress/index.js +424 -0
  113. package/esm/utils/murmur3/{commons.js → common.js} +1 -4
  114. package/esm/utils/murmur3/murmur3.js +1 -2
  115. package/esm/utils/murmur3/murmur3_128.js +7 -142
  116. package/esm/utils/murmur3/murmur3_128_x86.js +150 -0
  117. package/esm/utils/murmur3/murmur3_64.js +32 -0
  118. package/esm/utils/murmur3/utfx.js +96 -106
  119. package/esm/utils/promise/wrapper.js +14 -11
  120. package/esm/utils/settingsValidation/index.js +5 -2
  121. package/esm/utils/settingsValidation/localhost/index.js +16 -0
  122. package/esm/utils/settingsValidation/splitFilters.js +0 -1
  123. package/esm/utils/settingsValidation/storage/storageCS.js +16 -7
  124. package/esm/utils/settingsValidation/url.js +1 -1
  125. package/package.json +5 -5
  126. package/src/evaluator/matchers/matcherTypes.ts +2 -2
  127. package/src/evaluator/matchersTransform/index.ts +12 -12
  128. package/src/evaluator/value/sanitize.ts +7 -7
  129. package/src/listeners/browser.ts +1 -1
  130. package/src/listeners/node.ts +1 -2
  131. package/src/logger/constants.ts +2 -0
  132. package/src/logger/messages/error.ts +3 -2
  133. package/src/logger/messages/info.ts +2 -2
  134. package/src/logger/messages/warn.ts +3 -1
  135. package/src/readiness/readinessManager.ts +9 -7
  136. package/src/sdkFactory/index.ts +1 -3
  137. package/src/sdkFactory/types.ts +3 -3
  138. package/src/services/splitApi.ts +2 -3
  139. package/src/services/splitHttpClient.ts +6 -5
  140. package/src/services/types.ts +5 -5
  141. package/src/storages/AbstractSplitsCacheSync.ts +1 -1
  142. package/src/storages/inLocalStorage/index.ts +8 -4
  143. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  144. package/src/storages/inMemory/InMemoryStorageCS.ts +3 -0
  145. package/src/storages/inRedis/SplitsCacheInRedis.ts +3 -1
  146. package/src/storages/inRedis/index.ts +8 -4
  147. package/src/storages/pluggable/SplitsCachePluggable.ts +3 -1
  148. package/src/storages/pluggable/inMemoryWrapper.ts +6 -7
  149. package/src/storages/pluggable/index.ts +8 -4
  150. package/src/storages/pluggable/wrapperAdapter.ts +0 -1
  151. package/src/storages/types.ts +18 -15
  152. package/src/sync/offline/splitsParser/splitsParserFromFile.ts +110 -105
  153. package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +45 -41
  154. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +15 -5
  155. package/src/sync/polling/types.ts +2 -1
  156. package/src/sync/polling/updaters/mySegmentsUpdater.ts +28 -10
  157. package/src/sync/streaming/AuthClient/types.ts +3 -0
  158. package/src/sync/streaming/SSEClient/index.ts +1 -15
  159. package/src/sync/streaming/SSEClient/types.ts +0 -1
  160. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +8 -0
  161. package/src/sync/streaming/SSEHandler/NotificationParser.ts +4 -2
  162. package/src/sync/streaming/SSEHandler/index.ts +11 -20
  163. package/src/sync/streaming/SSEHandler/types.ts +37 -3
  164. package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +7 -6
  165. package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +2 -1
  166. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +4 -3
  167. package/src/sync/streaming/UpdateWorkers/types.ts +1 -1
  168. package/src/sync/streaming/constants.ts +2 -0
  169. package/src/sync/streaming/mySegmentsV2utils.ts +77 -0
  170. package/src/sync/streaming/pushManager.ts +139 -42
  171. package/src/sync/streaming/types.ts +14 -22
  172. package/src/sync/submitters/metricsSyncTask.ts +1 -1
  173. package/src/sync/submitters/submitterSyncTask.ts +2 -1
  174. package/src/sync/syncManagerFromFile.ts +13 -0
  175. package/src/sync/syncManagerFromObject.ts +12 -0
  176. package/src/sync/syncManagerOffline.ts +3 -3
  177. package/src/sync/syncManagerOnline.ts +6 -3
  178. package/src/trackers/impressionObserver/ImpressionObserver.ts +4 -6
  179. package/src/trackers/impressionObserver/buildKey.ts +2 -16
  180. package/src/trackers/impressionObserver/impressionObserverCS.ts +2 -2
  181. package/src/trackers/impressionObserver/impressionObserverSS.ts +3 -3
  182. package/src/types.ts +16 -2
  183. package/src/utils/constants/index.ts +6 -1
  184. package/src/utils/decompress/index.ts +429 -0
  185. package/src/utils/murmur3/{commons.ts → common.ts} +1 -5
  186. package/src/utils/murmur3/murmur3.ts +5 -5
  187. package/src/utils/murmur3/murmur3_128.ts +7 -180
  188. package/src/utils/murmur3/murmur3_128_x86.ts +188 -0
  189. package/src/utils/murmur3/murmur3_64.ts +36 -0
  190. package/src/utils/murmur3/utfx.ts +92 -110
  191. package/src/utils/promise/wrapper.ts +12 -9
  192. package/src/utils/settingsValidation/index.ts +8 -4
  193. package/src/utils/settingsValidation/localhost/index.ts +19 -0
  194. package/src/utils/settingsValidation/splitFilters.ts +0 -1
  195. package/src/utils/settingsValidation/storage/storageCS.ts +21 -8
  196. package/src/utils/settingsValidation/types.ts +2 -11
  197. package/src/utils/settingsValidation/url.ts +1 -1
  198. package/types/evaluator/matchers/matcherTypes.d.ts +2 -2
  199. package/types/listeners/browser.d.ts +1 -0
  200. package/types/listeners/node.d.ts +0 -1
  201. package/types/logger/constants.d.ts +2 -0
  202. package/types/sdkFactory/types.d.ts +3 -3
  203. package/types/services/types.d.ts +1 -0
  204. package/types/storages/inLocalStorage/index.d.ts +2 -2
  205. package/types/storages/inMemory/InMemoryStorage.d.ts +3 -0
  206. package/types/storages/inMemory/InMemoryStorageCS.d.ts +3 -0
  207. package/types/storages/inRedis/index.d.ts +2 -2
  208. package/types/storages/pluggable/index.d.ts +2 -2
  209. package/types/storages/types.d.ts +15 -15
  210. package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -7
  211. package/types/sync/offline/splitsParser/splitsParserFromSettings.d.ts +1 -5
  212. package/types/sync/polling/types.d.ts +2 -1
  213. package/types/sync/streaming/AuthClient/indexV1.d.ts +12 -0
  214. package/types/sync/streaming/AuthClient/indexV2.d.ts +8 -0
  215. package/types/sync/streaming/AuthClient/types.d.ts +2 -0
  216. package/types/sync/streaming/SSEClient/index.d.ts +1 -9
  217. package/types/sync/streaming/SSEClient/types.d.ts +0 -1
  218. package/types/sync/streaming/SSEHandler/NotificationParser.d.ts +3 -2
  219. package/types/sync/streaming/SSEHandler/types.d.ts +30 -2
  220. package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +4 -3
  221. package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +2 -1
  222. package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +3 -2
  223. package/types/sync/streaming/UpdateWorkers/types.d.ts +1 -1
  224. package/types/sync/streaming/constants.d.ts +3 -1
  225. package/types/sync/streaming/mySegmentsV2utils.d.ts +27 -0
  226. package/types/sync/streaming/pushManagerNoUsers.d.ts +13 -0
  227. package/types/sync/streaming/types.d.ts +9 -5
  228. package/types/sync/submitters/submitterSyncTask.d.ts +1 -1
  229. package/types/sync/syncManagerFromFile.d.ts +2 -0
  230. package/types/sync/syncManagerFromObject.d.ts +2 -0
  231. package/types/sync/syncManagerOffline.d.ts +1 -1
  232. package/types/trackers/impressionObserver/ImpressionObserver.d.ts +2 -2
  233. package/types/trackers/impressionObserver/buildKey.d.ts +1 -1
  234. package/types/trackers/impressionObserver/impressionObserverCS.d.ts +2 -2
  235. package/types/trackers/impressionObserver/impressionObserverSS.d.ts +2 -2
  236. package/types/types.d.ts +16 -2
  237. package/types/utils/constants/index.d.ts +5 -1
  238. package/types/utils/decompress/index.d.ts +16 -0
  239. package/types/utils/murmur3/common.d.ts +12 -0
  240. package/types/utils/murmur3/murmur3.d.ts +2 -2
  241. package/types/utils/murmur3/murmur3_128.d.ts +5 -0
  242. package/types/utils/murmur3/murmur3_128_x86.d.ts +7 -0
  243. package/types/utils/murmur3/murmur3_64.d.ts +10 -0
  244. package/types/utils/murmur3/utfx.d.ts +24 -6
  245. package/types/utils/settingsValidation/index.d.ts +3 -2
  246. package/types/utils/settingsValidation/localhost/index.d.ts +9 -0
  247. package/types/utils/settingsValidation/storage/storageCS.d.ts +7 -1
  248. package/types/utils/settingsValidation/types.d.ts +2 -10
  249. package/cjs/sync/streaming/pushManagerCS.js +0 -179
  250. package/cjs/sync/streaming/pushManagerSS.js +0 -128
  251. package/esm/sync/streaming/pushManagerCS.js +0 -175
  252. package/esm/sync/streaming/pushManagerSS.js +0 -124
  253. package/src/sync/streaming/pushManagerCS.ts +0 -238
  254. package/src/sync/streaming/pushManagerSS.ts +0 -177
@@ -1,175 +0,0 @@
1
- import objectAssign from 'object-assign';
2
- import { MY_SEGMENTS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP } from './constants';
3
- import Backoff from '../../utils/Backoff';
4
- import SSEHandlerFactory from './SSEHandler';
5
- import MySegmentsUpdateWorker from './UpdateWorkers/MySegmentsUpdateWorker';
6
- import SplitsUpdateWorker from './UpdateWorkers/SplitsUpdateWorker';
7
- import { authenticateFactory, hashUserKey } from './AuthClient';
8
- import { forOwn } from '../../utils/lang';
9
- import SSEClient from './SSEClient';
10
- import { getMatching } from '../../utils/key';
11
- import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT } from '../../logger/constants';
12
- /**
13
- * PushManager factory for client-side, with support for multiple clients.
14
- * It assumes settings contains a key.
15
- */
16
- export default function pushManagerCSFactory(pollingManager, storage, readiness, fetchAuth, platform, settings) {
17
- var log = settings.log;
18
- var sseClient;
19
- try {
20
- // `useHeaders` false for client-side, even if the platform EventSource supports headers (e.g., React Native).
21
- sseClient = new SSEClient(settings, false, platform.getEventSource);
22
- }
23
- catch (e) {
24
- log.warn(STREAMING_FALLBACK, [e]);
25
- return;
26
- }
27
- var authenticate = authenticateFactory(fetchAuth);
28
- // init feedback loop
29
- var pushEmitter = new platform.EventEmitter();
30
- var sseHandler = SSEHandlerFactory(log, pushEmitter);
31
- sseClient.setEventHandler(sseHandler);
32
- // [Only for client-side] map of hashes to user keys, to dispatch MY_SEGMENTS_UPDATE events to the corresponding MySegmentsUpdateWorker
33
- var userKeyHashes = {};
34
- var userKey = getMatching(settings.core.key); // matching key of main client
35
- var hash = hashUserKey(userKey);
36
- userKeyHashes[hash] = userKey;
37
- // [Only for client-side] map of user keys to their corresponding MySegmentsUpdateWorkers. It has a two-fold intention:
38
- // - stop workers all together when push is disconnected
39
- // - keep the current list of user keys to authenticate
40
- var workers = {};
41
- // init workers
42
- var mySegmentsUpdateWorker = new MySegmentsUpdateWorker(pollingManager.segmentsSyncTask);
43
- workers[userKey] = mySegmentsUpdateWorker;
44
- var splitsUpdateWorker = new SplitsUpdateWorker(storage.splits, pollingManager.splitsSyncTask, readiness.splits);
45
- // [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
46
- var connectForNewClient = false;
47
- // flag that indicates if `disconnectPush` was called, either by the SyncManager (when the client is destroyed) or by a PUSH_NONRETRYABLE_ERROR error.
48
- // It is used to halt the `connectPush` process if it was in progress.
49
- var disconnected;
50
- /** PushManager functions related to initialization */
51
- var connectPushRetryBackoff = new Backoff(connectPush, settings.scheduler.pushRetryBackoffBase);
52
- var timeoutId;
53
- function scheduleTokenRefresh(issuedAt, expirationTime) {
54
- // clear scheduled token refresh if exists (needed when resuming PUSH)
55
- if (timeoutId)
56
- clearTimeout(timeoutId);
57
- // Set token refresh 10 minutes before expirationTime
58
- var delayInSeconds = expirationTime - issuedAt - SECONDS_BEFORE_EXPIRATION;
59
- log.info(STREAMING_REFRESH_TOKEN, [delayInSeconds]);
60
- timeoutId = setTimeout(connectPush, delayInSeconds * 1000);
61
- }
62
- function connectPush() {
63
- disconnected = false;
64
- log.info(STREAMING_CONNECTING);
65
- var userKeys = Object.keys(workers); // [Only for client-side]
66
- authenticate(userKeys).then(function (authData) {
67
- if (disconnected)
68
- return;
69
- // 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
70
- // close the sseClient in case the org has been bloqued while the instance was connected to streaming
71
- if (!authData.pushEnabled) {
72
- log.info(STREAMING_DISABLED);
73
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
74
- return;
75
- }
76
- // [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
77
- if (userKeys && userKeys.length < Object.keys(workers).length)
78
- return;
79
- // Connect to SSE and schedule refresh token
80
- var decodedToken = authData.decodedToken;
81
- sseClient.open(authData);
82
- scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
83
- }).catch(function (error) {
84
- if (disconnected)
85
- return;
86
- log.error(ERROR_STREAMING_AUTH, [error.message]);
87
- // Handle 4XX HTTP errors: 401 (invalid API Key) or 400 (using incorrect API Key, i.e., client-side API Key on server-side)
88
- if (error.statusCode >= 400 && error.statusCode < 500) {
89
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
90
- return;
91
- }
92
- // Handle other HTTP and network errors as recoverable errors
93
- pushEmitter.emit(PUSH_RETRYABLE_ERROR);
94
- });
95
- }
96
- // close SSE connection and cancel scheduled tasks
97
- function disconnectPush() {
98
- sseClient.close();
99
- disconnected = true;
100
- log.info(STREAMING_DISCONNECTING);
101
- if (timeoutId)
102
- clearTimeout(timeoutId);
103
- connectPushRetryBackoff.reset();
104
- stopWorkers();
105
- }
106
- // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
107
- function stopWorkers() {
108
- splitsUpdateWorker.backoff.reset();
109
- forOwn(workers, function (worker) { return worker.backoff.reset(); });
110
- }
111
- pushEmitter.on(PUSH_SUBSYSTEM_DOWN, stopWorkers);
112
- // restart backoff retry counter once push is connected
113
- pushEmitter.on(PUSH_SUBSYSTEM_UP, function () { connectPushRetryBackoff.reset(); });
114
- /** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
115
- pushEmitter.on(PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
116
- // Note: `stopWorkers` is been called twice, but it is not harmful
117
- disconnectPush();
118
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
119
- });
120
- /** Fallbacking with retry due to recoverable SSE and Authentication errors */
121
- pushEmitter.on(PUSH_RETRYABLE_ERROR, function handleRetryableError() {
122
- // SSE connection is closed to avoid repeated errors due to retries
123
- sseClient.close();
124
- // retry streaming reconnect with backoff algorithm
125
- var delayInMillis = connectPushRetryBackoff.scheduleCall();
126
- log.info(STREAMING_RECONNECT, [delayInMillis / 1000]);
127
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
128
- });
129
- /** Functions related to synchronization (Queues and Workers in the spec) */
130
- pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
131
- pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
132
- // [Only for client-side]
133
- pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
134
- var userKeyHash = channel.split('_')[2];
135
- var userKey = userKeyHashes[userKeyHash];
136
- if (userKey && workers[userKey]) { // check context since it can be undefined if client has been destroyed
137
- var mySegmentsUpdateWorker_1 = workers[userKey];
138
- mySegmentsUpdateWorker_1.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
139
- }
140
- });
141
- return objectAssign(
142
- // Expose Event Emitter functionality and Event constants
143
- Object.create(pushEmitter), {
144
- // Expose functionality for starting and stoping push mode:
145
- stop: disconnectPush,
146
- start: function () {
147
- // Run in next event-loop cycle for optimization: if multiple clients are created in the same cycle than the factory, only one authentication is performed.
148
- setTimeout(connectPush);
149
- },
150
- // [Only for client-side]
151
- add: function (userKey, mySegmentsSyncTask) {
152
- var mySegmentsUpdateWorker = new MySegmentsUpdateWorker(mySegmentsSyncTask);
153
- workers[userKey] = mySegmentsUpdateWorker;
154
- var hash = hashUserKey(userKey);
155
- if (!userKeyHashes[hash]) {
156
- userKeyHashes[hash] = userKey;
157
- connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
158
- }
159
- // Reconnects in case of a new client.
160
- // Run in next event-loop cycle to save authentication calls
161
- // in case the user is creating several clients in the current cycle.
162
- setTimeout(function checkForReconnect() {
163
- if (connectForNewClient) {
164
- connectForNewClient = false;
165
- connectPush();
166
- }
167
- }, 0);
168
- },
169
- // [Only for client-side]
170
- remove: function (userKey) {
171
- var hash = hashUserKey(userKey);
172
- delete userKeyHashes[hash];
173
- }
174
- });
175
- }
@@ -1,124 +0,0 @@
1
- import objectAssign from 'object-assign';
2
- import { PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP } from './constants';
3
- import Backoff from '../../utils/Backoff';
4
- import SSEHandlerFactory from './SSEHandler';
5
- import SegmentsUpdateWorker from './UpdateWorkers/SegmentsUpdateWorker';
6
- import SplitsUpdateWorker from './UpdateWorkers/SplitsUpdateWorker';
7
- import { authenticateFactory } from './AuthClient';
8
- import SSEClient from './SSEClient';
9
- import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT } from '../../logger/constants';
10
- /**
11
- * PushManager factory for server-side
12
- */
13
- export default function pushManagerSSFactory(pollingManager, storage, readiness, fetchAuth, platform, settings) {
14
- var log = settings.log;
15
- var sseClient;
16
- try {
17
- sseClient = new SSEClient(settings, true, platform.getEventSource);
18
- }
19
- catch (e) {
20
- log.warn(STREAMING_FALLBACK, [e]);
21
- return;
22
- }
23
- var authenticate = authenticateFactory(fetchAuth);
24
- // init feedback loop (pushEmitter)
25
- var pushEmitter = new platform.EventEmitter();
26
- var sseHandler = SSEHandlerFactory(log, pushEmitter);
27
- sseClient.setEventHandler(sseHandler);
28
- // init workers
29
- var splitsUpdateWorker = new SplitsUpdateWorker(storage.splits, pollingManager.splitsSyncTask, readiness.splits, pollingManager.segmentsSyncTask);
30
- var segmentsUpdateWorker = new SegmentsUpdateWorker(storage.segments, pollingManager.segmentsSyncTask);
31
- // flag that indicates if `disconnectPush` was called, either by the SyncManager (when the client is destroyed) or by a PUSH_NONRETRYABLE_ERROR error.
32
- // It is used to halt the `connectPush` process if it was in progress.
33
- var disconnected;
34
- /** PushManager functions related to initialization */
35
- var connectPushRetryBackoff = new Backoff(connectPush, settings.scheduler.pushRetryBackoffBase);
36
- var timeoutId;
37
- function scheduleTokenRefresh(issuedAt, expirationTime) {
38
- // clear scheduled token refresh if exists (needed when resuming PUSH)
39
- if (timeoutId)
40
- clearTimeout(timeoutId);
41
- // Set token refresh 10 minutes before expirationTime
42
- var delayInSeconds = expirationTime - issuedAt - SECONDS_BEFORE_EXPIRATION;
43
- log.info(STREAMING_REFRESH_TOKEN, [delayInSeconds]);
44
- timeoutId = setTimeout(connectPush, delayInSeconds * 1000);
45
- }
46
- function connectPush() {
47
- disconnected = false;
48
- log.info(STREAMING_CONNECTING);
49
- authenticate().then(function (authData) {
50
- if (disconnected)
51
- return;
52
- // 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
53
- // close the sseClient in case the org has been bloqued while the instance was connected to streaming
54
- if (!authData.pushEnabled) {
55
- log.info(STREAMING_DISABLED);
56
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
57
- return;
58
- }
59
- // Connect to SSE and schedule refresh token
60
- var decodedToken = authData.decodedToken;
61
- sseClient.open(authData);
62
- scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
63
- }).catch(function (error) {
64
- if (disconnected)
65
- return;
66
- log.error(ERROR_STREAMING_AUTH, [error.message]);
67
- // Handle 4XX HTTP errors: 401 (invalid API Key) or 400 (using incorrect API Key, i.e., client-side API Key on server-side)
68
- if (error.statusCode >= 400 && error.statusCode < 500) {
69
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
70
- return;
71
- }
72
- // Handle other HTTP and network errors as recoverable errors
73
- pushEmitter.emit(PUSH_RETRYABLE_ERROR);
74
- });
75
- }
76
- // close SSE connection and cancel scheduled tasks
77
- function disconnectPush() {
78
- sseClient.close();
79
- disconnected = true;
80
- log.info(STREAMING_DISCONNECTING);
81
- if (timeoutId)
82
- clearTimeout(timeoutId);
83
- connectPushRetryBackoff.reset();
84
- stopWorkers();
85
- }
86
- // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
87
- function stopWorkers() {
88
- splitsUpdateWorker.backoff.reset();
89
- segmentsUpdateWorker.backoff.reset();
90
- }
91
- pushEmitter.on(PUSH_SUBSYSTEM_DOWN, stopWorkers);
92
- // restart backoff retry counter once push is connected
93
- pushEmitter.on(PUSH_SUBSYSTEM_UP, function () { connectPushRetryBackoff.reset(); });
94
- /** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
95
- pushEmitter.on(PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
96
- // Note: `stopWorkers` is been called twice, but it is not harmful
97
- disconnectPush();
98
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
99
- });
100
- /** Fallbacking with retry due to recoverable SSE and Authentication errors */
101
- pushEmitter.on(PUSH_RETRYABLE_ERROR, function handleRetryableError() {
102
- // SSE connection is closed to avoid repeated errors due to retries
103
- sseClient.close();
104
- // retry streaming reconnect with backoff algorithm
105
- var delayInMillis = connectPushRetryBackoff.scheduleCall();
106
- log.info(STREAMING_RECONNECT, [delayInMillis / 1000]);
107
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
108
- });
109
- /** Functions related to synchronization (Queues and Workers in the spec) */
110
- pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
111
- pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
112
- // [Only for server-side]
113
- pushEmitter.on(SEGMENT_UPDATE, segmentsUpdateWorker.put);
114
- return objectAssign(
115
- // Expose Event Emitter functionality and Event constants
116
- Object.create(pushEmitter), {
117
- // Expose functionality for starting and stoping push mode:
118
- stop: disconnectPush,
119
- start: function () {
120
- // Run in next event-loop cycle as in browser
121
- setTimeout(connectPush);
122
- }
123
- });
124
- }
@@ -1,238 +0,0 @@
1
- import { IPushEventEmitter, IPushManagerCS } from './types';
2
- import { ISSEClient } from './SSEClient/types';
3
- import { IStorageSync } from '../../storages/types';
4
- import { IReadinessManager } from '../../readiness/types';
5
- import { ISegmentsSyncTask, IPollingManager } from '../polling/types';
6
- import { IUpdateWorker } from './UpdateWorkers/types';
7
- import objectAssign from 'object-assign';
8
- import { MY_SEGMENTS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP } from './constants';
9
- import Backoff from '../../utils/Backoff';
10
- import SSEHandlerFactory from './SSEHandler';
11
- import MySegmentsUpdateWorker from './UpdateWorkers/MySegmentsUpdateWorker';
12
- import SplitsUpdateWorker from './UpdateWorkers/SplitsUpdateWorker';
13
- import { authenticateFactory, hashUserKey } from './AuthClient';
14
- import { forOwn } from '../../utils/lang';
15
- import SSEClient from './SSEClient';
16
- import { IFetchAuth } from '../../services/types';
17
- import { ISettings } from '../../types';
18
- import { getMatching } from '../../utils/key';
19
- import { IPlatform } from '../../sdkFactory/types';
20
- import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT } from '../../logger/constants';
21
-
22
- /**
23
- * PushManager factory for client-side, with support for multiple clients.
24
- * It assumes settings contains a key.
25
- */
26
- export default function pushManagerCSFactory(
27
- pollingManager: IPollingManager,
28
- storage: IStorageSync,
29
- readiness: IReadinessManager,
30
- fetchAuth: IFetchAuth,
31
- platform: IPlatform,
32
- settings: ISettings
33
- ): IPushManagerCS | undefined {
34
-
35
- const log = settings.log;
36
-
37
- let sseClient: ISSEClient;
38
- try {
39
- // `useHeaders` false for client-side, even if the platform EventSource supports headers (e.g., React Native).
40
- sseClient = new SSEClient(settings, false, platform.getEventSource);
41
- } catch (e) {
42
- log.warn(STREAMING_FALLBACK, [e]);
43
- return;
44
- }
45
- const authenticate = authenticateFactory(fetchAuth);
46
-
47
- // init feedback loop
48
- const pushEmitter = new platform.EventEmitter() as IPushEventEmitter;
49
- const sseHandler = SSEHandlerFactory(log, pushEmitter);
50
- sseClient.setEventHandler(sseHandler);
51
-
52
- // [Only for client-side] map of hashes to user keys, to dispatch MY_SEGMENTS_UPDATE events to the corresponding MySegmentsUpdateWorker
53
- const userKeyHashes: Record<string, string> = {};
54
- const userKey = getMatching(settings.core.key); // matching key of main client
55
- const hash = hashUserKey(userKey);
56
- userKeyHashes[hash] = userKey;
57
-
58
- // [Only for client-side] map of user keys to their corresponding MySegmentsUpdateWorkers. It has a two-fold intention:
59
- // - stop workers all together when push is disconnected
60
- // - keep the current list of user keys to authenticate
61
- const workers: Record<string, IUpdateWorker> = {};
62
-
63
- // init workers
64
- const mySegmentsUpdateWorker = new MySegmentsUpdateWorker(pollingManager.segmentsSyncTask);
65
- workers[userKey] = mySegmentsUpdateWorker;
66
- const splitsUpdateWorker = new SplitsUpdateWorker(storage.splits, pollingManager.splitsSyncTask, readiness.splits);
67
-
68
- // [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
69
- let connectForNewClient = false;
70
-
71
- // flag that indicates if `disconnectPush` was called, either by the SyncManager (when the client is destroyed) or by a PUSH_NONRETRYABLE_ERROR error.
72
- // It is used to halt the `connectPush` process if it was in progress.
73
- let disconnected: boolean | undefined;
74
-
75
- /** PushManager functions related to initialization */
76
-
77
- const connectPushRetryBackoff = new Backoff(connectPush, settings.scheduler.pushRetryBackoffBase);
78
-
79
- let timeoutId: ReturnType<typeof setTimeout>;
80
-
81
- function scheduleTokenRefresh(issuedAt: number, expirationTime: number) {
82
- // clear scheduled token refresh if exists (needed when resuming PUSH)
83
- if (timeoutId) clearTimeout(timeoutId);
84
-
85
- // Set token refresh 10 minutes before expirationTime
86
- const delayInSeconds = expirationTime - issuedAt - SECONDS_BEFORE_EXPIRATION;
87
-
88
- log.info(STREAMING_REFRESH_TOKEN, [delayInSeconds]);
89
-
90
- timeoutId = setTimeout(connectPush, delayInSeconds * 1000);
91
- }
92
-
93
- function connectPush() {
94
- disconnected = false;
95
- log.info(STREAMING_CONNECTING);
96
-
97
- const userKeys = Object.keys(workers); // [Only for client-side]
98
- authenticate(userKeys).then(
99
- function (authData) {
100
- if (disconnected) return;
101
-
102
- // 'pushEnabled: false' is handled as a PUSH_NONRETRYABLE_ERROR instead of PUSH_SUBSYSTEM_DOWN, in order to
103
- // close the sseClient in case the org has been bloqued while the instance was connected to streaming
104
- if (!authData.pushEnabled) {
105
- log.info(STREAMING_DISABLED);
106
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
107
- return;
108
- }
109
-
110
- // [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
111
- if (userKeys && userKeys.length < Object.keys(workers).length) return;
112
-
113
- // Connect to SSE and schedule refresh token
114
- const decodedToken = authData.decodedToken;
115
- sseClient.open(authData);
116
- scheduleTokenRefresh(decodedToken.iat, decodedToken.exp);
117
- }
118
- ).catch(
119
- function (error) {
120
- if (disconnected) return;
121
-
122
- log.error(ERROR_STREAMING_AUTH, [error.message]);
123
-
124
- // Handle 4XX HTTP errors: 401 (invalid API Key) or 400 (using incorrect API Key, i.e., client-side API Key on server-side)
125
- if (error.statusCode >= 400 && error.statusCode < 500) {
126
- pushEmitter.emit(PUSH_NONRETRYABLE_ERROR);
127
- return;
128
- }
129
-
130
- // Handle other HTTP and network errors as recoverable errors
131
- pushEmitter.emit(PUSH_RETRYABLE_ERROR);
132
- }
133
- );
134
- }
135
-
136
- // close SSE connection and cancel scheduled tasks
137
- function disconnectPush() {
138
- sseClient.close();
139
- disconnected = true;
140
- log.info(STREAMING_DISCONNECTING);
141
-
142
- if (timeoutId) clearTimeout(timeoutId);
143
- connectPushRetryBackoff.reset();
144
-
145
- stopWorkers();
146
- }
147
-
148
- // cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
149
- function stopWorkers() {
150
- splitsUpdateWorker.backoff.reset();
151
- forOwn(workers, worker => worker.backoff.reset());
152
- }
153
-
154
- pushEmitter.on(PUSH_SUBSYSTEM_DOWN, stopWorkers);
155
-
156
- // restart backoff retry counter once push is connected
157
- pushEmitter.on(PUSH_SUBSYSTEM_UP, () => { connectPushRetryBackoff.reset(); });
158
-
159
- /** Fallbacking without retry due to: STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE and Authentication errors */
160
-
161
- pushEmitter.on(PUSH_NONRETRYABLE_ERROR, function handleNonRetryableError() {
162
- // Note: `stopWorkers` is been called twice, but it is not harmful
163
- disconnectPush();
164
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
165
- });
166
-
167
- /** Fallbacking with retry due to recoverable SSE and Authentication errors */
168
-
169
- pushEmitter.on(PUSH_RETRYABLE_ERROR, function handleRetryableError() { // HTTP or network error in SSE connection
170
- // SSE connection is closed to avoid repeated errors due to retries
171
- sseClient.close();
172
-
173
- // retry streaming reconnect with backoff algorithm
174
- let delayInMillis = connectPushRetryBackoff.scheduleCall();
175
-
176
- log.info(STREAMING_RECONNECT, [delayInMillis / 1000]);
177
-
178
- pushEmitter.emit(PUSH_SUBSYSTEM_DOWN); // no harm if polling already
179
- });
180
-
181
- /** Functions related to synchronization (Queues and Workers in the spec) */
182
-
183
- pushEmitter.on(SPLIT_KILL, splitsUpdateWorker.killSplit);
184
- pushEmitter.on(SPLIT_UPDATE, splitsUpdateWorker.put);
185
- // [Only for client-side]
186
- pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
187
- const userKeyHash = channel.split('_')[2];
188
- const userKey = userKeyHashes[userKeyHash];
189
- if (userKey && workers[userKey]) { // check context since it can be undefined if client has been destroyed
190
- const mySegmentsUpdateWorker = workers[userKey];
191
- mySegmentsUpdateWorker.put(
192
- parsedData.changeNumber,
193
- parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
194
- }
195
- });
196
-
197
- return objectAssign(
198
- // Expose Event Emitter functionality and Event constants
199
- Object.create(pushEmitter),
200
- {
201
- // Expose functionality for starting and stoping push mode:
202
- stop: disconnectPush, // `handleNonRetryableError` cannot be used as `stop`, because it emits PUSH_SUBSYSTEM_DOWN event, which start polling.
203
-
204
- start() {
205
- // Run in next event-loop cycle for optimization: if multiple clients are created in the same cycle than the factory, only one authentication is performed.
206
- setTimeout(connectPush);
207
- },
208
-
209
- // [Only for client-side]
210
- add(userKey: string, mySegmentsSyncTask: ISegmentsSyncTask) {
211
- const mySegmentsUpdateWorker = new MySegmentsUpdateWorker(mySegmentsSyncTask);
212
- workers[userKey] = mySegmentsUpdateWorker;
213
-
214
- const hash = hashUserKey(userKey);
215
-
216
- if (!userKeyHashes[hash]) {
217
- userKeyHashes[hash] = userKey;
218
- connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
219
- }
220
-
221
- // Reconnects in case of a new client.
222
- // Run in next event-loop cycle to save authentication calls
223
- // in case the user is creating several clients in the current cycle.
224
- setTimeout(function checkForReconnect() {
225
- if (connectForNewClient) {
226
- connectForNewClient = false;
227
- connectPush();
228
- }
229
- }, 0);
230
- },
231
- // [Only for client-side]
232
- remove(userKey: string) {
233
- const hash = hashUserKey(userKey);
234
- delete userKeyHashes[hash];
235
- }
236
- }
237
- );
238
- }