@splitsoftware/splitio-commons 1.2.1-rc.1 → 1.2.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 (289) hide show
  1. package/cjs/consent/index.js +10 -0
  2. package/cjs/consent/sdkUserConsent.js +58 -0
  3. package/cjs/evaluator/Engine.js +6 -6
  4. package/cjs/evaluator/combiners/and.js +1 -1
  5. package/cjs/evaluator/combiners/ifelseif.js +2 -2
  6. package/cjs/evaluator/condition/engineUtils.js +2 -2
  7. package/cjs/evaluator/condition/index.js +4 -4
  8. package/cjs/evaluator/index.js +5 -5
  9. package/cjs/evaluator/matchers/cont_all.js +1 -1
  10. package/cjs/evaluator/matchers/cont_any.js +1 -1
  11. package/cjs/evaluator/matchers/cont_str.js +1 -1
  12. package/cjs/evaluator/matchers/dependency.js +1 -1
  13. package/cjs/evaluator/matchers/eq_set.js +1 -1
  14. package/cjs/evaluator/matchers/ew.js +1 -1
  15. package/cjs/evaluator/matchers/part_of.js +1 -1
  16. package/cjs/evaluator/matchers/segment.js +1 -1
  17. package/cjs/evaluator/matchers/sw.js +1 -1
  18. package/cjs/evaluator/matchers/whitelist.js +1 -1
  19. package/cjs/evaluator/matchersTransform/index.js +12 -12
  20. package/cjs/evaluator/parser/index.js +6 -6
  21. package/cjs/evaluator/treatments/index.js +1 -1
  22. package/cjs/evaluator/value/index.js +1 -1
  23. package/cjs/evaluator/value/sanitize.js +4 -4
  24. package/cjs/integrations/browser.js +3 -3
  25. package/cjs/integrations/ga/GaToSplit.js +14 -14
  26. package/cjs/integrations/ga/GoogleAnalyticsToSplit.js +5 -3
  27. package/cjs/integrations/ga/SplitToGa.js +1 -1
  28. package/cjs/integrations/ga/SplitToGoogleAnalytics.js +4 -2
  29. package/cjs/listeners/browser.js +15 -11
  30. package/cjs/listeners/node.js +1 -1
  31. package/cjs/logger/constants.js +9 -3
  32. package/cjs/logger/index.js +2 -2
  33. package/cjs/logger/messages/debug.js +4 -4
  34. package/cjs/logger/messages/error.js +5 -4
  35. package/cjs/logger/messages/info.js +8 -5
  36. package/cjs/logger/messages/warn.js +1 -1
  37. package/cjs/logger/sdkLogger.js +1 -1
  38. package/cjs/readiness/readinessManager.js +2 -2
  39. package/cjs/readiness/sdkReadinessManager.js +4 -4
  40. package/cjs/sdkClient/client.js +12 -11
  41. package/cjs/sdkClient/clientAttributesDecoration.js +4 -4
  42. package/cjs/sdkClient/clientCS.js +3 -3
  43. package/cjs/sdkClient/clientInputValidation.js +20 -22
  44. package/cjs/sdkClient/sdkClient.js +6 -9
  45. package/cjs/sdkClient/sdkClientMethod.js +1 -1
  46. package/cjs/sdkClient/sdkClientMethodCS.js +7 -13
  47. package/cjs/sdkClient/sdkClientMethodCSWithTT.js +8 -18
  48. package/cjs/sdkFactory/index.js +16 -13
  49. package/cjs/sdkManager/index.js +11 -11
  50. package/cjs/services/splitApi.js +3 -2
  51. package/cjs/services/splitHttpClient.js +2 -2
  52. package/cjs/storages/KeyBuilder.js +2 -6
  53. package/cjs/storages/KeyBuilderCS.js +13 -3
  54. package/cjs/storages/KeyBuilderSS.js +1 -1
  55. package/cjs/storages/findLatencyIndex.js +1 -1
  56. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +24 -4
  57. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +12 -12
  58. package/cjs/storages/inLocalStorage/index.js +4 -4
  59. package/cjs/storages/inMemory/AttributesCacheInMemory.js +1 -1
  60. package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
  61. package/cjs/storages/inMemory/ImpressionsCacheInMemory.js +15 -1
  62. package/cjs/storages/inMemory/InMemoryStorage.js +1 -1
  63. package/cjs/storages/inMemory/InMemoryStorageCS.js +1 -1
  64. package/cjs/storages/inMemory/LatenciesCacheInMemory.js +1 -1
  65. package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
  66. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +2 -2
  67. package/cjs/storages/inMemory/SplitsCacheInMemory.js +5 -5
  68. package/cjs/storages/inRedis/LatenciesCacheInRedis.js +1 -1
  69. package/cjs/storages/inRedis/RedisAdapter.js +24 -11
  70. package/cjs/storages/inRedis/SegmentsCacheInRedis.js +1 -1
  71. package/cjs/storages/inRedis/SplitsCacheInRedis.js +3 -3
  72. package/cjs/storages/inRedis/index.js +1 -1
  73. package/cjs/storages/pluggable/SegmentsCachePluggable.js +1 -1
  74. package/cjs/storages/pluggable/SplitsCachePluggable.js +3 -3
  75. package/cjs/storages/pluggable/inMemoryWrapper.js +4 -4
  76. package/cjs/storages/pluggable/index.js +6 -6
  77. package/cjs/sync/offline/LocalhostFromFile.js +1 -1
  78. package/cjs/sync/offline/LocalhostFromObject.js +1 -1
  79. package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
  80. package/cjs/sync/offline/splitsParser/splitsParserFromFile.js +13 -13
  81. package/cjs/sync/offline/splitsParser/splitsParserFromSettings.js +3 -3
  82. package/cjs/sync/offline/syncManagerOffline.js +1 -1
  83. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +2 -2
  84. package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
  85. package/cjs/sync/polling/pollingManagerCS.js +6 -6
  86. package/cjs/sync/polling/pollingManagerSS.js +3 -3
  87. package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +1 -1
  88. package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +1 -1
  89. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  90. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +1 -1
  91. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +2 -2
  92. package/cjs/sync/polling/updaters/splitChangesUpdater.js +2 -2
  93. package/cjs/sync/streaming/AuthClient/index.js +3 -3
  94. package/cjs/sync/streaming/SSEClient/index.js +2 -1
  95. package/cjs/sync/streaming/SSEHandler/NotificationParser.js +1 -1
  96. package/cjs/sync/streaming/SSEHandler/index.js +3 -3
  97. package/cjs/sync/streaming/mySegmentsV2utils.js +1 -1
  98. package/cjs/sync/streaming/pushManager.js +24 -17
  99. package/cjs/sync/submitters/eventsSyncTask.js +17 -5
  100. package/cjs/sync/submitters/impressionCountsSyncTask.js +1 -1
  101. package/cjs/sync/submitters/impressionsSyncTask.js +15 -3
  102. package/cjs/sync/submitters/metricsSyncTask.js +3 -3
  103. package/cjs/sync/submitters/submitterManager.js +4 -4
  104. package/cjs/sync/submitters/submitterSyncTask.js +1 -1
  105. package/cjs/sync/syncManagerOnline.js +12 -8
  106. package/cjs/trackers/eventTracker.js +11 -4
  107. package/cjs/trackers/impressionObserver/impressionObserverCS.js +1 -1
  108. package/cjs/trackers/impressionObserver/impressionObserverSS.js +1 -1
  109. package/cjs/trackers/impressionObserver/utils.js +8 -1
  110. package/cjs/trackers/impressionsTracker.js +9 -8
  111. package/cjs/utils/MinEvents.js +2 -1
  112. package/cjs/utils/constants/index.js +5 -1
  113. package/cjs/utils/inputValidation/apiKey.js +1 -1
  114. package/cjs/utils/inputValidation/attribute.js +4 -4
  115. package/cjs/utils/inputValidation/attributes.js +2 -2
  116. package/cjs/utils/inputValidation/event.js +1 -1
  117. package/cjs/utils/inputValidation/eventProperties.js +5 -5
  118. package/cjs/utils/inputValidation/eventValue.js +1 -1
  119. package/cjs/utils/inputValidation/key.js +6 -5
  120. package/cjs/utils/inputValidation/preloadedData.js +8 -8
  121. package/cjs/utils/inputValidation/split.js +1 -1
  122. package/cjs/utils/inputValidation/splits.js +2 -2
  123. package/cjs/utils/inputValidation/trafficType.js +1 -1
  124. package/cjs/utils/inputValidation/trafficTypeExistance.js +1 -1
  125. package/cjs/utils/jwt/index.js +1 -1
  126. package/cjs/utils/key/index.js +3 -3
  127. package/cjs/utils/lang/index.js +13 -4
  128. package/cjs/utils/lang/maps.js +16 -2
  129. package/cjs/utils/murmur3/common.js +1 -1
  130. package/cjs/utils/murmur3/murmur3.js +10 -10
  131. package/cjs/utils/murmur3/murmur3_128.js +1 -1
  132. package/cjs/utils/murmur3/murmur3_128_x86.js +37 -37
  133. package/cjs/utils/murmur3/murmur3_64.js +1 -1
  134. package/cjs/utils/settingsValidation/consent.js +16 -0
  135. package/cjs/utils/settingsValidation/impressionsMode.js +6 -6
  136. package/cjs/utils/settingsValidation/index.js +32 -14
  137. package/cjs/utils/settingsValidation/integrations/configurable.js +1 -1
  138. package/cjs/utils/settingsValidation/integrations/pluggable.js +1 -1
  139. package/cjs/utils/settingsValidation/localhost/builtin.js +2 -2
  140. package/cjs/utils/settingsValidation/logger/builtinLogger.js +3 -3
  141. package/cjs/utils/settingsValidation/logger/commons.js +1 -1
  142. package/cjs/utils/settingsValidation/logger/pluggableLogger.js +1 -1
  143. package/cjs/utils/settingsValidation/runtime.js +11 -0
  144. package/cjs/utils/settingsValidation/splitFilters.js +1 -1
  145. package/cjs/utils/settingsValidation/storage/storageCS.js +1 -1
  146. package/cjs/utils/timeTracker/index.js +3 -3
  147. package/esm/consent/index.js +6 -0
  148. package/esm/consent/sdkUserConsent.js +54 -0
  149. package/esm/integrations/ga/GoogleAnalyticsToSplit.js +4 -2
  150. package/esm/integrations/ga/SplitToGoogleAnalytics.js +4 -2
  151. package/esm/listeners/browser.js +14 -10
  152. package/esm/logger/constants.js +6 -2
  153. package/esm/logger/messages/debug.js +3 -3
  154. package/esm/logger/messages/error.js +4 -3
  155. package/esm/logger/messages/info.js +7 -4
  156. package/esm/sdkClient/client.js +3 -2
  157. package/esm/sdkClient/clientCS.js +1 -1
  158. package/esm/sdkClient/clientInputValidation.js +6 -8
  159. package/esm/sdkClient/sdkClient.js +4 -7
  160. package/esm/sdkClient/sdkClientMethodCS.js +3 -9
  161. package/esm/sdkClient/sdkClientMethodCSWithTT.js +3 -13
  162. package/esm/sdkFactory/index.js +10 -7
  163. package/esm/services/splitApi.js +2 -1
  164. package/esm/storages/KeyBuilder.js +2 -6
  165. package/esm/storages/KeyBuilderCS.js +11 -1
  166. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +23 -3
  167. package/esm/storages/inLocalStorage/index.js +1 -1
  168. package/esm/storages/inMemory/ImpressionsCacheInMemory.js +15 -1
  169. package/esm/storages/inMemory/InMemoryStorage.js +1 -1
  170. package/esm/storages/inMemory/InMemoryStorageCS.js +1 -1
  171. package/esm/storages/inRedis/RedisAdapter.js +15 -2
  172. package/esm/storages/pluggable/index.js +2 -2
  173. package/esm/sync/offline/splitsParser/splitsParserFromFile.js +1 -1
  174. package/esm/sync/polling/fetchers/segmentChangesFetcher.js +2 -2
  175. package/esm/sync/streaming/SSEClient/index.js +2 -1
  176. package/esm/sync/streaming/pushManager.js +9 -2
  177. package/esm/sync/submitters/eventsSyncTask.js +18 -6
  178. package/esm/sync/submitters/impressionsSyncTask.js +13 -1
  179. package/esm/sync/syncManagerOnline.js +11 -7
  180. package/esm/trackers/eventTracker.js +8 -1
  181. package/esm/trackers/impressionObserver/utils.js +7 -1
  182. package/esm/trackers/impressionsTracker.js +6 -5
  183. package/esm/utils/constants/index.js +4 -0
  184. package/esm/utils/inputValidation/attributes.js +1 -1
  185. package/esm/utils/inputValidation/key.js +2 -1
  186. package/esm/utils/lang/index.js +12 -4
  187. package/esm/utils/lang/maps.js +14 -1
  188. package/esm/utils/settingsValidation/consent.js +12 -0
  189. package/esm/utils/settingsValidation/impressionsMode.js +7 -7
  190. package/esm/utils/settingsValidation/index.js +28 -10
  191. package/esm/utils/settingsValidation/runtime.js +7 -0
  192. package/package.json +8 -8
  193. package/src/consent/index.ts +8 -0
  194. package/src/consent/sdkUserConsent.ts +58 -0
  195. package/src/evaluator/parser/index.ts +1 -1
  196. package/src/evaluator/types.ts +2 -2
  197. package/src/evaluator/value/index.ts +2 -2
  198. package/src/evaluator/value/sanitize.ts +2 -2
  199. package/src/integrations/ga/GoogleAnalyticsToSplit.ts +7 -4
  200. package/src/integrations/ga/SplitToGoogleAnalytics.ts +7 -4
  201. package/src/integrations/pluggable.ts +2 -2
  202. package/src/integrations/types.ts +5 -0
  203. package/src/listeners/browser.ts +13 -9
  204. package/src/logger/constants.ts +6 -2
  205. package/src/logger/messages/debug.ts +3 -3
  206. package/src/logger/messages/error.ts +4 -3
  207. package/src/logger/messages/info.ts +7 -4
  208. package/src/logger/types.ts +4 -0
  209. package/src/sdkClient/client.ts +5 -5
  210. package/src/sdkClient/clientCS.ts +1 -1
  211. package/src/sdkClient/clientInputValidation.ts +8 -7
  212. package/src/sdkClient/sdkClient.ts +6 -9
  213. package/src/sdkClient/sdkClientMethod.ts +2 -2
  214. package/src/sdkClient/sdkClientMethodCS.ts +5 -11
  215. package/src/sdkClient/sdkClientMethodCSWithTT.ts +6 -16
  216. package/src/sdkFactory/index.ts +11 -8
  217. package/src/sdkFactory/types.ts +14 -3
  218. package/src/storages/KeyBuilder.ts +2 -6
  219. package/src/storages/KeyBuilderCS.ts +13 -1
  220. package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +23 -3
  221. package/src/storages/inLocalStorage/index.ts +1 -1
  222. package/src/storages/inMemory/ImpressionsCacheInMemory.ts +22 -1
  223. package/src/storages/inMemory/InMemoryStorage.ts +1 -1
  224. package/src/storages/inMemory/InMemoryStorageCS.ts +1 -1
  225. package/src/storages/inRedis/RedisAdapter.ts +8 -2
  226. package/src/storages/pluggable/index.ts +2 -2
  227. package/src/storages/types.ts +6 -2
  228. package/src/sync/offline/splitsParser/splitsParserFromFile.ts +1 -1
  229. package/src/sync/streaming/SSEClient/index.ts +2 -1
  230. package/src/sync/streaming/pushManager.ts +11 -2
  231. package/src/sync/submitters/eventsSyncTask.ts +19 -6
  232. package/src/sync/submitters/impressionsSyncTask.ts +16 -1
  233. package/src/sync/syncManagerOnline.ts +13 -7
  234. package/src/sync/types.ts +4 -1
  235. package/src/trackers/eventTracker.ts +11 -3
  236. package/src/trackers/impressionObserver/utils.ts +8 -1
  237. package/src/trackers/impressionsTracker.ts +7 -8
  238. package/src/types.ts +22 -1
  239. package/src/utils/constants/index.ts +5 -0
  240. package/src/utils/inputValidation/attributes.ts +1 -2
  241. package/src/utils/lang/index.ts +15 -4
  242. package/src/utils/lang/maps.ts +15 -1
  243. package/src/utils/settingsValidation/consent.ts +16 -0
  244. package/src/utils/settingsValidation/impressionsMode.ts +8 -8
  245. package/src/utils/settingsValidation/index.ts +29 -10
  246. package/src/utils/settingsValidation/runtime.ts +9 -0
  247. package/src/utils/settingsValidation/types.ts +12 -6
  248. package/types/consent/index.d.ts +2 -0
  249. package/types/consent/sdkUserConsent.d.ts +13 -0
  250. package/types/evaluator/types.d.ts +2 -2
  251. package/types/evaluator/value/index.d.ts +1 -1
  252. package/types/evaluator/value/sanitize.d.ts +1 -1
  253. package/types/integrations/ga/GoogleAnalyticsToSplit.d.ts +2 -2
  254. package/types/integrations/ga/SplitToGoogleAnalytics.d.ts +2 -3
  255. package/types/integrations/types.d.ts +4 -0
  256. package/types/logger/constants.d.ts +6 -2
  257. package/types/logger/types.d.ts +4 -0
  258. package/types/sdkClient/client.d.ts +2 -2
  259. package/types/sdkClient/clientAttributesDecoration.d.ts +1 -1
  260. package/types/sdkClient/clientInputValidation.d.ts +2 -3
  261. package/types/sdkClient/sdkClient.d.ts +2 -2
  262. package/types/sdkClient/sdkClientMethod.d.ts +2 -2
  263. package/types/sdkClient/sdkClientMethodCS.d.ts +2 -2
  264. package/types/sdkClient/sdkClientMethodCSWithTT.d.ts +2 -2
  265. package/types/sdkFactory/types.d.ts +12 -3
  266. package/types/sdkFactory/userConsentProps.d.ts +6 -0
  267. package/types/storages/KeyBuilderCS.d.ts +2 -0
  268. package/types/storages/inMemory/ImpressionsCacheInMemory.d.ts +9 -0
  269. package/types/storages/inRedis/RedisAdapter.d.ts +1 -1
  270. package/types/storages/types.d.ts +3 -1
  271. package/types/sync/types.d.ts +3 -0
  272. package/types/trackers/eventTracker.d.ts +2 -2
  273. package/types/trackers/impressionObserver/utils.d.ts +4 -0
  274. package/types/trackers/impressionsTracker.d.ts +2 -3
  275. package/types/types.d.ts +22 -1
  276. package/types/utils/consent.d.ts +2 -0
  277. package/types/utils/constants/index.d.ts +3 -0
  278. package/types/utils/lang/index.d.ts +6 -1
  279. package/types/utils/lang/maps.d.ts +7 -0
  280. package/types/utils/settingsValidation/consent.d.ts +6 -0
  281. package/types/utils/settingsValidation/impressionsMode.d.ts +1 -1
  282. package/types/utils/settingsValidation/runtime/browser.d.ts +2 -0
  283. package/types/utils/settingsValidation/runtime/node.d.ts +2 -0
  284. package/types/utils/settingsValidation/runtime.d.ts +2 -0
  285. package/types/utils/settingsValidation/types.d.ts +12 -6
  286. package/types/utils/settingsValidation/userConsent.d.ts +5 -0
  287. package/cjs/sdkClient/types.js +0 -2
  288. package/esm/sdkClient/types.js +0 -1
  289. package/src/sdkClient/types.ts +0 -21
@@ -25,6 +25,6 @@ export function clientCSDecorator(log: ILogger, client: SplitIO.IClient, key: Sp
25
25
  // Key is bound to the `track` method. Same thing happens with trafficType but only if provided
26
26
  track: trafficType ? clientCS.track.bind(clientCS, key, trafficType) : clientCS.track.bind(clientCS, key),
27
27
 
28
- isBrowserClient: true
28
+ isClientSide: true
29
29
  }) as SplitIO.ICsClient;
30
30
  }
@@ -15,14 +15,17 @@ import { startsWith } from '../utils/lang';
15
15
  import { CONTROL, CONTROL_WITH_CONFIG } from '../utils/constants';
16
16
  import { IReadinessManager } from '../readiness/types';
17
17
  import { MaybeThenable } from '../dtos/types';
18
- import { SplitIO } from '../types';
19
- import { ILogger } from '../logger/types';
18
+ import { ISettings, SplitIO } from '../types';
19
+ import { isStorageSync } from '../trackers/impressionObserver/utils';
20
20
 
21
21
  /**
22
22
  * Decorator that validates the input before actually executing the client methods.
23
23
  * We should "guard" the client here, while not polluting the "real" implementation of those methods.
24
24
  */
25
- export function clientInputValidationDecorator<TClient extends SplitIO.IClient | SplitIO.IAsyncClient>(log: ILogger, client: TClient, readinessManager: IReadinessManager, isStorageSync = false): TClient {
25
+ export function clientInputValidationDecorator<TClient extends SplitIO.IClient | SplitIO.IAsyncClient>(settings: ISettings, client: TClient, readinessManager: IReadinessManager): TClient {
26
+
27
+ const log = settings.log;
28
+ const isSync = isStorageSync(settings);
26
29
 
27
30
  /**
28
31
  * Avoid repeating this validations code
@@ -47,8 +50,7 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
47
50
  }
48
51
 
49
52
  function wrapResult<T>(value: T): MaybeThenable<T> {
50
- if (isStorageSync) return value;
51
- return Promise.resolve(value);
53
+ return isSync ? value : Promise.resolve(value);
52
54
  }
53
55
 
54
56
  function getTreatment(maybeKey: SplitIO.SplitKey, maybeSplit: string, maybeAttributes?: SplitIO.Attributes) {
@@ -108,8 +110,7 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
108
110
  if (isOperational && key && tt && event && eventValue !== false && properties !== false) { // @ts-expect-error
109
111
  return client.track(key, tt, event, eventValue, properties, size);
110
112
  } else {
111
- if (isStorageSync) return false;
112
- return Promise.resolve(false);
113
+ return isSync ? false : Promise.resolve(false);
113
114
  }
114
115
  }
115
116
 
@@ -1,16 +1,15 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import { IStatusInterface, SplitIO } from '../types';
3
- import { CONSUMER_MODE, CONSUMER_PARTIAL_MODE } from '../utils/constants';
4
3
  import { releaseApiKey } from '../utils/inputValidation/apiKey';
5
4
  import { clientFactory } from './client';
6
5
  import { clientInputValidationDecorator } from './clientInputValidation';
7
- import { ISdkClientFactoryParams } from './types';
6
+ import { ISdkFactoryContext } from '../sdkFactory/types';
8
7
 
9
8
  /**
10
9
  * Creates an Sdk client, i.e., a base client with status and destroy interface
11
10
  */
12
- export function sdkClientFactory(params: ISdkClientFactoryParams): SplitIO.IClient | SplitIO.IAsyncClient {
13
- const { sdkReadinessManager, syncManager, storage, signalListener, settings, sharedClient } = params;
11
+ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: boolean): SplitIO.IClient | SplitIO.IAsyncClient {
12
+ const { sdkReadinessManager, syncManager, storage, signalListener, settings } = params;
14
13
 
15
14
  return objectAssign(
16
15
  // Proto-linkage of the readiness Event Emitter
@@ -18,11 +17,9 @@ export function sdkClientFactory(params: ISdkClientFactoryParams): SplitIO.IClie
18
17
 
19
18
  // Client API (getTreatment* & track methods)
20
19
  clientInputValidationDecorator(
21
- settings.log,
20
+ settings,
22
21
  clientFactory(params),
23
- sdkReadinessManager.readinessManager,
24
- // storage is async if and only if mode is consumer or partial consumer
25
- [CONSUMER_MODE, CONSUMER_PARTIAL_MODE].indexOf(settings.mode) === -1 ? true : false,
22
+ sdkReadinessManager.readinessManager
26
23
  ),
27
24
 
28
25
  // Sdk destroy
@@ -38,7 +35,7 @@ export function sdkClientFactory(params: ISdkClientFactoryParams): SplitIO.IClie
38
35
  signalListener && signalListener.stop();
39
36
 
40
37
  // Release the API Key if it is the main client
41
- if (!sharedClient) releaseApiKey(settings.core.authorizationKey);
38
+ if (!isSharedClient) releaseApiKey(settings.core.authorizationKey);
42
39
 
43
40
  // Cleanup storage
44
41
  return storage.destroy();
@@ -1,12 +1,12 @@
1
- import { ISdkClientFactoryParams } from './types';
2
1
  import { SplitIO } from '../types';
3
2
  import { sdkClientFactory } from './sdkClient';
4
3
  import { RETRIEVE_CLIENT_DEFAULT } from '../logger/constants';
4
+ import { ISdkFactoryContext } from '../sdkFactory/types';
5
5
 
6
6
  /**
7
7
  * Factory of client method for server-side SDKs (ISDK and IAsyncSDK)
8
8
  */
9
- export function sdkClientMethodFactory(params: ISdkClientFactoryParams): () => SplitIO.IClient | SplitIO.IAsyncClient {
9
+ export function sdkClientMethodFactory(params: ISdkFactoryContext): () => SplitIO.IClient | SplitIO.IAsyncClient {
10
10
  const log = params.settings.log;
11
11
  const clientInstance = sdkClientFactory(params);
12
12
 
@@ -1,5 +1,4 @@
1
1
  import { clientCSDecorator } from './clientCS';
2
- import { ISdkClientFactoryParams } from './types';
3
2
  import { SplitIO } from '../types';
4
3
  import { validateKey } from '../utils/inputValidation/key';
5
4
  import { getMatching, keyParser } from '../utils/key';
@@ -8,6 +7,7 @@ import { ISyncManagerCS } from '../sync/types';
8
7
  import { objectAssign } from '../utils/lang/objectAssign';
9
8
  import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING } from '../logger/constants';
10
9
  import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
10
+ import { ISdkFactoryContext } from '../sdkFactory/types';
11
11
 
12
12
  function buildInstanceId(key: SplitIO.SplitKey) {
13
13
  // @ts-ignore
@@ -20,18 +20,13 @@ const method = 'Client instantiation';
20
20
  * Factory of client method for the client-side API variant where TT is ignored and thus
21
21
  * clients don't have a binded TT for the track method.
22
22
  */
23
- export function sdkClientMethodCSFactory(params: ISdkClientFactoryParams): (key?: SplitIO.SplitKey) => SplitIO.ICsClient {
23
+ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey) => SplitIO.ICsClient {
24
24
  const { storage, syncManager, sdkReadinessManager, settings: { core: { key }, startup: { readyTimeout }, log } } = params;
25
25
 
26
- // Keeping similar behaviour as in the isomorphic JS SDK: if settings key is invalid,
27
- // `false` value is used as binded key of the default client, but trafficType is ignored
28
- // @TODO handle as a non-recoverable error
29
- const validKey = validateKey(log, key, method);
30
-
31
26
  const mainClientInstance = clientCSDecorator(
32
27
  log,
33
- sdkClientFactory(params) as SplitIO.IClient, // @ts-ignore
34
- validKey
28
+ sdkClientFactory(params) as SplitIO.IClient,
29
+ key
35
30
  );
36
31
 
37
32
  const parsedDefaultKey = keyParser(key);
@@ -81,8 +76,7 @@ export function sdkClientMethodCSFactory(params: ISdkClientFactoryParams): (key?
81
76
  storage: sharedStorage || storage,
82
77
  syncManager: sharedSyncManager,
83
78
  signalListener: undefined, // only the main client "destroy" method stops the signal listener
84
- sharedClient: true
85
- })) as SplitIO.IClient,
79
+ }), true) as SplitIO.IClient,
86
80
  validKey
87
81
  );
88
82
 
@@ -1,5 +1,4 @@
1
1
  import { clientCSDecorator } from './clientCS';
2
- import { ISdkClientFactoryParams } from './types';
3
2
  import { SplitIO } from '../types';
4
3
  import { validateKey } from '../utils/inputValidation/key';
5
4
  import { validateTrafficType } from '../utils/inputValidation/trafficType';
@@ -9,6 +8,7 @@ import { ISyncManagerCS } from '../sync/types';
9
8
  import { objectAssign } from '../utils/lang/objectAssign';
10
9
  import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING } from '../logger/constants';
11
10
  import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
11
+ import { ISdkFactoryContext } from '../sdkFactory/types';
12
12
 
13
13
  function buildInstanceId(key: SplitIO.SplitKey, trafficType?: string) {
14
14
  // @ts-ignore
@@ -22,23 +22,14 @@ const method = 'Client instantiation';
22
22
  * where clients can have a binded TT for the track method, which is provided via the settings
23
23
  * (default client) or the client method (shared clients).
24
24
  */
25
- export function sdkClientMethodCSFactory(params: ISdkClientFactoryParams): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
25
+ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
26
26
  const { storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType }, startup: { readyTimeout }, log } } = params;
27
27
 
28
- // Keeping the behaviour as in the isomorphic JS SDK: if settings key or TT are invalid,
29
- // `false` value is used as binded key/TT of the default client, which leads to several issues.
30
- // @TODO update when supporting non-recoverable errors
31
- const validKey = validateKey(log, key, method);
32
- let validTrafficType;
33
- if (trafficType !== undefined) {
34
- validTrafficType = validateTrafficType(log, trafficType, method);
35
- }
36
-
37
28
  const mainClientInstance = clientCSDecorator(
38
29
  log,
39
- sdkClientFactory(params) as SplitIO.IClient, // @ts-ignore
40
- validKey,
41
- validTrafficType
30
+ sdkClientFactory(params) as SplitIO.IClient,
31
+ key,
32
+ trafficType
42
33
  );
43
34
 
44
35
  const parsedDefaultKey = keyParser(key);
@@ -95,8 +86,7 @@ export function sdkClientMethodCSFactory(params: ISdkClientFactoryParams): (key?
95
86
  storage: sharedStorage || storage,
96
87
  syncManager: sharedSyncManager,
97
88
  signalListener: undefined, // only the main client "destroy" method stops the signal listener
98
- sharedClient: true
99
- })) as SplitIO.IClient,
89
+ }), true) as SplitIO.IClient,
100
90
  validKey,
101
91
  validTrafficType
102
92
  );
@@ -12,14 +12,15 @@ import { createLoggerAPI } from '../logger/sdkLogger';
12
12
  import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
13
13
  import { metadataBuilder } from '../storages/metadataBuilder';
14
14
  import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
15
+ import { objectAssign } from '../utils/lang/objectAssign';
15
16
 
16
17
  /**
17
18
  * Modular SDK factory
18
19
  */
19
20
  export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.ISDK | SplitIO.IAsyncSDK {
20
21
 
21
- const { settings, platform, storageFactory, splitApiFactory,
22
- syncManagerFactory, SignalListener, impressionsObserverFactory, impressionListener,
22
+ const { settings, platform, storageFactory, splitApiFactory, extraProps,
23
+ syncManagerFactory, SignalListener, impressionsObserverFactory,
23
24
  integrationsManagerFactory, sdkManagerFactory, sdkClientMethodFactory } = params;
24
25
  const log = settings.log;
25
26
 
@@ -33,6 +34,7 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
33
34
 
34
35
  // @TODO consider passing the settings object, so that each storage access only what it needs
35
36
  const storageFactoryParams: IStorageFactoryParams = {
37
+ impressionsQueueSize: settings.scheduler.impressionsQueueSize,
36
38
  eventsQueueSize: settings.scheduler.eventsQueueSize,
37
39
  optimize: shouldBeOptimized(settings),
38
40
 
@@ -72,14 +74,15 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
72
74
 
73
75
  // trackers
74
76
  const observer = impressionsObserverFactory && impressionsObserverFactory();
75
- const impressionsTracker = impressionsTrackerFactory(log, storage.impressions, settings, impressionListener, integrationsManager, observer, storage.impressionCounts);
76
- const eventTracker = eventTrackerFactory(log, storage.events, integrationsManager);
77
+ const impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, integrationsManager, observer, storage.impressionCounts);
78
+ const eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager);
77
79
 
78
80
  // signal listener
79
81
  const signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
80
82
 
81
83
  // Sdk client and manager
82
- const clientMethod = sdkClientMethodFactory({ eventTracker, impressionsTracker, sdkReadinessManager, settings, storage, syncManager, signalListener });
84
+ const ctx = { eventTracker, impressionsTracker, sdkReadinessManager, settings, storage, syncManager, signalListener };
85
+ const clientMethod = sdkClientMethodFactory(ctx);
83
86
  const managerInstance = sdkManagerFactory(log, storage.splits, sdkReadinessManager);
84
87
 
85
88
  syncManager && syncManager.start();
@@ -87,12 +90,12 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
87
90
 
88
91
  log.info(NEW_FACTORY);
89
92
 
90
- return {
93
+ // @ts-ignore
94
+ return objectAssign({
91
95
  // Split evaluation and event tracking engine
92
96
  client: clientMethod,
93
97
 
94
98
  // Manager API to explore available information
95
- // @ts-ignore
96
99
  manager() {
97
100
  log.debug(RETRIEVE_MANAGER);
98
101
  return managerInstance;
@@ -102,5 +105,5 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
102
105
  Logger: createLoggerAPI(settings.log),
103
106
 
104
107
  settings,
105
- };
108
+ }, extraProps && extraProps(ctx));
106
109
  }
@@ -2,13 +2,23 @@ import { IIntegrationManager, IIntegrationFactoryParams } from '../integrations/
2
2
  import { ISignalListener } from '../listeners/types';
3
3
  import { ILogger } from '../logger/types';
4
4
  import { ISdkReadinessManager } from '../readiness/types';
5
- import { ISdkClientFactoryParams } from '../sdkClient/types';
6
5
  import { IFetch, ISplitApi, IEventSourceConstructor } from '../services/types';
7
6
  import { IStorageAsync, IStorageSync, ISplitsCacheSync, ISplitsCacheAsync, IStorageFactoryParams } from '../storages/types';
8
7
  import { ISyncManager, ISyncManagerFactoryParams } from '../sync/types';
9
8
  import { IImpressionObserver } from '../trackers/impressionObserver/types';
9
+ import { IImpressionsTracker, IEventTracker } from '../trackers/types';
10
10
  import { SplitIO, ISettings, IEventEmitter } from '../types';
11
11
 
12
+ export interface ISdkFactoryContext {
13
+ storage: IStorageSync | IStorageAsync,
14
+ sdkReadinessManager: ISdkReadinessManager,
15
+ settings: ISettings
16
+ impressionsTracker: IImpressionsTracker,
17
+ eventTracker: IEventTracker,
18
+ signalListener?: ISignalListener
19
+ syncManager?: ISyncManager,
20
+ }
21
+
12
22
  /**
13
23
  * Environment related dependencies.
14
24
  * These getters are called a fixed number of times per factory instantiation.
@@ -53,7 +63,7 @@ export interface ISdkFactoryParams {
53
63
 
54
64
  // Sdk client method factory (ISDK::client method).
55
65
  // It Allows to distinguish SDK clients with the client-side API (`ICsSDK`) or server-side API (`ISDK` or `IAsyncSDK`).
56
- sdkClientMethodFactory: (params: ISdkClientFactoryParams) => ({ (): SplitIO.ICsClient; (key: SplitIO.SplitKey, trafficType?: string | undefined): SplitIO.ICsClient; } | (() => SplitIO.IClient) | (() => SplitIO.IAsyncClient))
66
+ sdkClientMethodFactory: (params: ISdkFactoryContext) => ({ (): SplitIO.ICsClient; (key: SplitIO.SplitKey, trafficType?: string | undefined): SplitIO.ICsClient; } | (() => SplitIO.IClient) | (() => SplitIO.IAsyncClient))
57
67
 
58
68
  // Optional signal listener constructor. Used to handle special app states, like shutdown, app paused or resumed.
59
69
  // Pass only if `syncManager` (used by Node listener) and `splitApi` (used by Browser listener) are passed.
@@ -64,10 +74,11 @@ export interface ISdkFactoryParams {
64
74
  serviceApi: ISplitApi | undefined) => ISignalListener, // Used by BrowserSignalListener
65
75
 
66
76
  // @TODO review impressionListener and integrations interfaces. What about handling impressionListener as an integration ?
67
- impressionListener?: SplitIO.IImpressionListener,
68
77
  integrationsManagerFactory?: (params: IIntegrationFactoryParams) => IIntegrationManager | undefined,
69
78
 
70
79
  // Impression observer factory. If provided, will be used for impressions dedupe
71
80
  impressionsObserverFactory?: () => IImpressionObserver
72
81
 
82
+ // Optional function to assign additional properties to the factory instance
83
+ extraProps?: (params: ISdkFactoryContext) => object
73
84
  }
@@ -1,15 +1,11 @@
1
- import { endsWith, startsWith } from '../utils/lang';
1
+ import { startsWith } from '../utils/lang';
2
2
 
3
3
  const everythingAtTheEnd = /[^.]+$/;
4
4
 
5
5
  const DEFAULT_PREFIX = 'SPLITIO';
6
6
 
7
7
  export function validatePrefix(prefix: unknown) {
8
- return prefix && typeof prefix === 'string' ?
9
- endsWith(prefix, '.' + DEFAULT_PREFIX) ?
10
- prefix : // suffix already appended
11
- prefix + '.' + DEFAULT_PREFIX : // append suffix
12
- DEFAULT_PREFIX; // use default prefix if none is provided
8
+ return prefix ? prefix + '.SPLITIO' : 'SPLITIO';
13
9
  }
14
10
 
15
11
  export class KeyBuilder {
@@ -16,10 +16,22 @@ export class KeyBuilderCS extends KeyBuilder {
16
16
  * @override
17
17
  */
18
18
  buildSegmentNameKey(segmentName: string) {
19
- return `${this.matchingKey}.${this.prefix}.segment.${segmentName}`;
19
+ return `${this.prefix}.${this.matchingKey}.segment.${segmentName}`;
20
20
  }
21
21
 
22
22
  extractSegmentName(builtSegmentKeyName: string) {
23
+ const prefix = `${this.prefix}.${this.matchingKey}.segment.`;
24
+
25
+ if (startsWith(builtSegmentKeyName, prefix))
26
+ return builtSegmentKeyName.substr(prefix.length);
27
+ }
28
+
29
+ // @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
30
+ buildOldSegmentNameKey(segmentName: string) {
31
+ return `${this.matchingKey}.${this.prefix}.segment.${segmentName}`;
32
+ }
33
+ // @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
34
+ extractOldSegmentKey(builtSegmentKeyName: string) {
23
35
  const prefix = `${this.matchingKey}.${this.prefix}.segment.`;
24
36
 
25
37
  if (startsWith(builtSegmentKeyName, prefix))
@@ -67,9 +67,29 @@ export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
67
67
 
68
68
  // Scan current values from localStorage
69
69
  const storedSegmentNames = Object.keys(localStorage).reduce((accum, key) => {
70
- const name = this.keys.extractSegmentName(key);
71
-
72
- if (name) accum.push(name);
70
+ let segmentName = this.keys.extractSegmentName(key);
71
+
72
+ if (segmentName) {
73
+ accum.push(segmentName);
74
+ } else {
75
+ // @BREAKING: This is only to clean up "old" keys. Remove this whole else code block.
76
+ segmentName = this.keys.extractOldSegmentKey(key);
77
+
78
+ if (segmentName) { // this was an old segment key, let's clean up.
79
+ const newSegmentKey = this.keys.buildSegmentNameKey(segmentName);
80
+ try {
81
+ // If the new format key is not there, create it.
82
+ if (!localStorage.getItem(newSegmentKey) && names.indexOf(segmentName) > -1) {
83
+ localStorage.setItem(newSegmentKey, DEFINED);
84
+ // we are migrating a segment, let's track it.
85
+ accum.push(segmentName);
86
+ }
87
+ localStorage.removeItem(key); // we migrated the current key, let's delete it.
88
+ } catch (e) {
89
+ this.log.error(e);
90
+ }
91
+ }
92
+ }
73
93
 
74
94
  return accum;
75
95
  }, [] as string[]);
@@ -40,7 +40,7 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
40
40
  return {
41
41
  splits: new SplitsCacheInLocal(log, keys, expirationTimestamp, params.splitFiltersValidation),
42
42
  segments: new MySegmentsCacheInLocal(log, keys),
43
- impressions: new ImpressionsCacheInMemory(),
43
+ impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
44
44
  impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
45
45
  events: new EventsCacheInMemory(params.eventsQueueSize),
46
46
 
@@ -3,13 +3,34 @@ import { ImpressionDTO } from '../../types';
3
3
 
4
4
  export class ImpressionsCacheInMemory implements IImpressionsCacheSync {
5
5
 
6
- private queue: ImpressionDTO[] = [];
6
+ private onFullQueue?: () => void;
7
+ private readonly maxQueue: number;
8
+ private queue: ImpressionDTO[];
9
+
10
+ /**
11
+ *
12
+ * @param impressionsQueueSize number of queued impressions to call onFullQueueCb.
13
+ * Default value is 0, that means no maximum value, in case we want to avoid this being triggered.
14
+ */
15
+ constructor(impressionsQueueSize: number = 0) {
16
+ this.maxQueue = impressionsQueueSize;
17
+ this.queue = [];
18
+ }
19
+
20
+ setOnFullQueueCb(cb: () => void) {
21
+ this.onFullQueue = cb;
22
+ }
7
23
 
8
24
  /**
9
25
  * Store impressions in sequential order
10
26
  */
11
27
  track(data: ImpressionDTO[]) {
12
28
  this.queue.push(...data);
29
+
30
+ // Check if the cache queue is full and we need to flush it.
31
+ if (this.maxQueue > 0 && this.queue.length >= this.maxQueue && this.onFullQueue) {
32
+ this.onFullQueue();
33
+ }
13
34
  }
14
35
 
15
36
  /**
@@ -16,7 +16,7 @@ export function InMemoryStorageFactory(params: IStorageFactoryParams): IStorageS
16
16
  return {
17
17
  splits: new SplitsCacheInMemory(),
18
18
  segments: new SegmentsCacheInMemory(),
19
- impressions: new ImpressionsCacheInMemory(),
19
+ impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
20
20
  impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
21
21
  events: new EventsCacheInMemory(params.eventsQueueSize),
22
22
 
@@ -16,7 +16,7 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
16
16
  return {
17
17
  splits: new SplitsCacheInMemory(),
18
18
  segments: new MySegmentsCacheInMemory(),
19
- impressions: new ImpressionsCacheInMemory(),
19
+ impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
20
20
  impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
21
21
  events: new EventsCacheInMemory(params.eventsQueueSize),
22
22
 
@@ -164,6 +164,12 @@ export class RedisAdapter extends ioredis {
164
164
  } else { // If it IS the string URL, that'll be the first param for ioredis.
165
165
  result.unshift(options.url);
166
166
  }
167
+ if (options.connectionTimeout) {
168
+ merge(opts, { connectTimeout: options.connectionTimeout });
169
+ }
170
+ if (options.tls) {
171
+ merge(opts, { tls: options.tls });
172
+ }
167
173
 
168
174
  return result;
169
175
  }
@@ -171,9 +177,9 @@ export class RedisAdapter extends ioredis {
171
177
  /**
172
178
  * Parses the options into what we care about.
173
179
  */
174
- static _defineOptions({ connectionTimeout, operationTimeout, url, host, port, db, pass }: Record<string, any>) {
180
+ static _defineOptions({ connectionTimeout, operationTimeout, url, host, port, db, pass, tls }: Record<string, any>) {
175
181
  const parsedOptions = {
176
- connectionTimeout, operationTimeout, url, host, port, db, pass
182
+ connectionTimeout, operationTimeout, url, host, port, db, pass, tls
177
183
  };
178
184
 
179
185
  return merge({}, DEFAULT_OPTIONS, parsedOptions);
@@ -63,7 +63,7 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
63
63
 
64
64
  const prefix = validatePrefix(options.prefix);
65
65
 
66
- function PluggableStorageFactory({ log, metadata, onReadyCb, mode, eventsQueueSize, optimize }: IStorageFactoryParams): IStorageAsync {
66
+ function PluggableStorageFactory({ log, metadata, onReadyCb, mode, eventsQueueSize, impressionsQueueSize, optimize }: IStorageFactoryParams): IStorageAsync {
67
67
  const keys = new KeyBuilderSS(prefix, metadata);
68
68
  const wrapper = wrapperAdapter(log, options.wrapper);
69
69
  const isPartialConsumer = mode === CONSUMER_PARTIAL_MODE;
@@ -74,7 +74,7 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
74
74
  return {
75
75
  splits: new SplitsCachePluggable(log, keys, wrapper),
76
76
  segments: new SegmentsCachePluggable(log, keys, wrapper),
77
- impressions: isPartialConsumer ? new ImpressionsCacheInMemory() : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
77
+ impressions: isPartialConsumer ? new ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
78
78
  impressionCounts: optimize ? new ImpressionCountsCacheInMemory() : undefined,
79
79
  events: isPartialConsumer ? promisifyEventsTrack(new EventsCacheInMemory(eventsQueueSize)) : new EventsCachePluggable(log, keys.buildEventsKey(), wrapper, metadata),
80
80
  // @TODO add telemetry cache when required
@@ -298,7 +298,7 @@ export interface IRecorderCacheProducerSync<T> {
298
298
  // @TODO names are inconsistent with spec
299
299
  /* Checks if cache is empty. Returns true if the cache was just created or cleared */
300
300
  isEmpty(): boolean
301
- /* clears cache data */
301
+ /* Clears cache data */
302
302
  clear(): void
303
303
  /* Gets cache data */
304
304
  state(): T
@@ -307,10 +307,13 @@ export interface IRecorderCacheProducerSync<T> {
307
307
 
308
308
  export interface IImpressionsCacheSync extends IImpressionsCacheBase, IRecorderCacheProducerSync<ImpressionDTO[]> {
309
309
  track(data: ImpressionDTO[]): void
310
+ /* Registers callback for full queue */
311
+ setOnFullQueueCb(cb: () => void): void
310
312
  }
311
313
 
312
314
  export interface IEventsCacheSync extends IEventsCacheBase, IRecorderCacheProducerSync<SplitIO.EventData[]> {
313
315
  track(data: SplitIO.EventData, size?: number): boolean
316
+ /* Registers callback for full queue */
314
317
  setOnFullQueueCb(cb: () => void): void
315
318
  }
316
319
 
@@ -423,6 +426,7 @@ export type DataLoader = (storage: IStorageSync, matchingKey: string) => void
423
426
 
424
427
  export interface IStorageFactoryParams {
425
428
  log: ILogger,
429
+ impressionsQueueSize?: number,
426
430
  eventsQueueSize?: number,
427
431
  optimize?: boolean /* whether create the `impressionCounts` cache (OPTIMIZED impression mode) or not (DEBUG impression mode) */,
428
432
 
@@ -443,7 +447,7 @@ export interface IStorageFactoryParams {
443
447
  export type StorageType = 'MEMORY' | 'LOCALSTORAGE' | 'REDIS' | 'PLUGGABLE';
444
448
 
445
449
  export type IStorageSyncFactory = {
446
- type: StorageType,
450
+ readonly type: StorageType,
447
451
  (params: IStorageFactoryParams): IStorageSync
448
452
  }
449
453
 
@@ -82,7 +82,7 @@ export function splitsParserFromFileFactory(): ISplitsParser {
82
82
  try {
83
83
  data = fs.readFileSync(filePath, 'utf-8');
84
84
  } catch (e) {
85
- log.error(e.message);
85
+ log.error(e && (e as Error).message);
86
86
 
87
87
  return {};
88
88
  }
@@ -1,5 +1,6 @@
1
1
  import { IEventSourceConstructor } from '../../../services/types';
2
2
  import { ISettings } from '../../../types';
3
+ import { isString } from '../../../utils/lang';
3
4
  import { IAuthTokenPushEnabled } from '../AuthClient/types';
4
5
  import { ISSEClient, ISseEventHandler } from './types';
5
6
 
@@ -15,7 +16,7 @@ const CONTROL_CHANNEL_REGEX = /^control_/;
15
16
  */
16
17
  function buildSSEHeaders(settings: ISettings) {
17
18
  const headers: Record<string, string> = {
18
- SplitSDKClientKey: settings.core.authorizationKey.slice(-4),
19
+ SplitSDKClientKey: isString(settings.core.authorizationKey) ? settings.core.authorizationKey.slice(-4) : '',
19
20
  SplitSDKVersion: settings.version,
20
21
  };
21
22
 
@@ -71,6 +71,7 @@ export function pushManagerFactory(
71
71
  // It is used to halt the `connectPush` process if it was in progress.
72
72
  let disconnected: boolean | undefined;
73
73
  // flag that indicates a PUSH_NONRETRYABLE_ERROR, condition with which starting pushManager again is ignored.
74
+ // true if STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE or Auth errors.
74
75
  let disabled: boolean | undefined; // `disabled` implies `disconnected === true`
75
76
 
76
77
  /** PushManager functions related to initialization */
@@ -296,12 +297,15 @@ export function pushManagerFactory(
296
297
  // Expose Event Emitter functionality and Event constants
297
298
  Object.create(pushEmitter),
298
299
  {
299
- // Stop/pause push mode
300
+ // Stop/pause push mode.
301
+ // It doesn't emit events. Neither PUSH_SUBSYSTEM_DOWN to start polling.
300
302
  stop() {
301
303
  disconnectPush(); // `handleNonRetryableError` cannot be used as `stop`, because it emits PUSH_SUBSYSTEM_DOWN event, which starts polling.
302
304
  if (userKey) this.remove(userKey); // Necessary to properly resume streaming in client-side (e.g., RN SDK transition to foreground).
303
305
  },
304
- // Start/resume push mode
306
+
307
+ // Start/resume push mode.
308
+ // It eventually emits PUSH_SUBSYSTEM_DOWN, that starts polling, or PUSH_SUBSYSTEM_UP, that executes a syncAll
305
309
  start() {
306
310
  // Guard condition to avoid calling `connectPush` again if the `start` method is called multiple times or if push has been disabled.
307
311
  if (disabled || disconnected === false) return;
@@ -311,6 +315,11 @@ export function pushManagerFactory(
311
315
  else setTimeout(connectPush); // server-side runs in next cycle as in client-side, for consistency with client-side
312
316
  },
313
317
 
318
+ // true/false if start or stop was called last respectively
319
+ isRunning(){
320
+ return disconnected === false;
321
+ },
322
+
314
323
  // [Only for client-side]
315
324
  add(userKey: string, mySegmentsSyncTask: ISegmentsSyncTask) {
316
325
  const hash = hashUserKey(userKey);