@splitsoftware/splitio-commons 2.12.0 → 3.0.0-rc.0

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 (309) hide show
  1. package/CHANGES.txt +14 -1
  2. package/cjs/evaluator/condition/engineUtils.js +2 -2
  3. package/cjs/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +70 -0
  4. package/cjs/evaluator/fallbackConfigsCalculator/index.js +25 -0
  5. package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  6. package/cjs/evaluator/fallbackTreatmentsCalculator/index.js +21 -32
  7. package/cjs/evaluator/index.js +67 -42
  8. package/cjs/evaluator/matchers/whitelist.js +1 -1
  9. package/cjs/integrations/pluggable.js +1 -1
  10. package/cjs/listeners/browser.js +4 -3
  11. package/cjs/listeners/node.js +4 -4
  12. package/cjs/logger/constants.js +14 -20
  13. package/cjs/logger/index.js +1 -1
  14. package/cjs/logger/messages/debug.js +6 -7
  15. package/cjs/logger/messages/error.js +4 -4
  16. package/cjs/logger/messages/info.js +2 -4
  17. package/cjs/logger/messages/warn.js +9 -9
  18. package/cjs/platform/browser.js +15 -0
  19. package/cjs/platform/getEventSource/browser.js +8 -0
  20. package/cjs/platform/getEventSource/eventsource.js +480 -0
  21. package/cjs/platform/getEventSource/node.js +26 -0
  22. package/cjs/platform/getFetch/browser.js +9 -0
  23. package/cjs/platform/getFetch/node.js +27 -0
  24. package/cjs/platform/getOptions/node.js +25 -0
  25. package/cjs/platform/node.js +17 -0
  26. package/cjs/readiness/constants.js +2 -1
  27. package/cjs/sdkClient/client.js +9 -35
  28. package/cjs/sdkClient/clientAttributesDecoration.js +3 -3
  29. package/cjs/sdkClient/clientInputValidation.js +38 -81
  30. package/cjs/sdkClient/identity.js +1 -1
  31. package/cjs/sdkClient/sdkClient.js +4 -49
  32. package/cjs/sdkClient/sdkLifecycle.js +70 -0
  33. package/cjs/sdkClient/trackMethod.js +56 -0
  34. package/cjs/sdkFactory/index.js +8 -45
  35. package/cjs/sdkManager/index.js +3 -3
  36. package/cjs/services/splitApi.js +18 -13
  37. package/cjs/services/splitHttpClient.js +1 -1
  38. package/cjs/storages/AbstractSplitsCacheAsync.js +1 -1
  39. package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
  40. package/cjs/storages/KeyBuilder.js +12 -12
  41. package/cjs/storages/KeyBuilderCS.js +13 -13
  42. package/cjs/storages/KeyBuilderSS.js +15 -15
  43. package/cjs/storages/getRolloutPlan.js +1 -1
  44. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -1
  45. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
  46. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +1 -1
  47. package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
  48. package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
  49. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
  50. package/cjs/storages/inMemory/SplitsCacheInMemory.js +1 -1
  51. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +2 -2
  52. package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
  53. package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +5 -5
  54. package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +1 -1
  55. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
  56. package/cjs/storages/inRedis/RedisAdapter.js +8 -8
  57. package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -6
  58. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +7 -7
  59. package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +3 -3
  60. package/cjs/storages/pluggable/EventsCachePluggable.js +1 -1
  61. package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +6 -6
  62. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
  63. package/cjs/storages/pluggable/SplitsCachePluggable.js +4 -4
  64. package/cjs/storages/pluggable/TelemetryCachePluggable.js +7 -7
  65. package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +2 -2
  66. package/cjs/storages/pluggable/index.js +3 -3
  67. package/cjs/storages/pluggable/wrapperAdapter.js +1 -1
  68. package/cjs/storages/setRolloutPlan.js +1 -1
  69. package/cjs/storages/utils.js +6 -6
  70. package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
  71. package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
  72. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +23 -14
  73. package/cjs/sync/polling/pollingManagerCS.js +11 -11
  74. package/cjs/sync/polling/pollingManagerSS.js +13 -13
  75. package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +12 -0
  76. package/cjs/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
  77. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +1 -1
  78. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
  79. package/cjs/sync/streaming/SSEClient/index.js +2 -2
  80. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
  81. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
  82. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
  83. package/cjs/sync/streaming/parseUtils.js +12 -12
  84. package/cjs/sync/streaming/pushManager.js +2 -2
  85. package/cjs/sync/submitters/impressionsSubmitter.js +6 -6
  86. package/cjs/sync/submitters/submitter.js +1 -1
  87. package/cjs/sync/syncManagerOnline.js +5 -2
  88. package/cjs/trackers/eventTracker.js +10 -12
  89. package/cjs/trackers/impressionObserver/buildKey.js +1 -1
  90. package/cjs/trackers/impressionsTracker.js +37 -20
  91. package/cjs/trackers/uniqueKeysTracker.js +1 -1
  92. package/cjs/utils/EventEmitter.js +391 -0
  93. package/cjs/utils/filter/bloomFilter.js +37 -0
  94. package/cjs/utils/inputValidation/apiKey.js +1 -1
  95. package/cjs/utils/inputValidation/attribute.js +2 -2
  96. package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
  97. package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
  98. package/cjs/utils/inputValidation/definitions.js +25 -0
  99. package/cjs/utils/inputValidation/eventProperties.js +1 -1
  100. package/cjs/utils/inputValidation/index.js +7 -7
  101. package/cjs/utils/inputValidation/isOperational.js +4 -4
  102. package/cjs/utils/inputValidation/target.js +22 -0
  103. package/cjs/utils/labels/index.js +3 -3
  104. package/cjs/utils/lang/index.js +1 -1
  105. package/cjs/utils/promise/timeout.js +1 -1
  106. package/cjs/utils/settingsValidation/splitFilters.js +4 -4
  107. package/cjs/utils/settingsValidation/url.js +5 -5
  108. package/esm/evaluator/condition/engineUtils.js +2 -2
  109. package/esm/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +64 -0
  110. package/esm/evaluator/fallbackConfigsCalculator/index.js +21 -0
  111. package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  112. package/esm/evaluator/fallbackTreatmentsCalculator/index.js +21 -33
  113. package/esm/evaluator/index.js +66 -42
  114. package/esm/evaluator/matchers/whitelist.js +1 -1
  115. package/esm/integrations/pluggable.js +1 -1
  116. package/esm/listeners/browser.js +4 -3
  117. package/esm/listeners/node.js +4 -4
  118. package/esm/logger/constants.js +11 -17
  119. package/esm/logger/index.js +1 -1
  120. package/esm/logger/messages/debug.js +5 -6
  121. package/esm/logger/messages/error.js +3 -3
  122. package/esm/logger/messages/info.js +1 -3
  123. package/esm/logger/messages/warn.js +8 -8
  124. package/esm/platform/browser.js +12 -0
  125. package/esm/platform/getEventSource/browser.js +4 -0
  126. package/esm/platform/getEventSource/eventsource.js +480 -0
  127. package/esm/platform/getEventSource/node.js +20 -0
  128. package/esm/platform/getFetch/browser.js +5 -0
  129. package/esm/platform/getFetch/node.js +22 -0
  130. package/esm/platform/getOptions/node.js +20 -0
  131. package/esm/platform/node.js +14 -0
  132. package/esm/readiness/constants.js +1 -0
  133. package/esm/sdkClient/client.js +10 -37
  134. package/esm/sdkClient/clientAttributesDecoration.js +3 -3
  135. package/esm/sdkClient/clientInputValidation.js +40 -83
  136. package/esm/sdkClient/identity.js +1 -1
  137. package/esm/sdkClient/sdkClient.js +4 -49
  138. package/esm/sdkClient/sdkLifecycle.js +66 -0
  139. package/esm/sdkClient/trackMethod.js +52 -0
  140. package/esm/sdkFactory/index.js +8 -45
  141. package/esm/sdkManager/index.js +4 -4
  142. package/esm/services/splitApi.js +18 -13
  143. package/esm/services/splitHttpClient.js +1 -1
  144. package/esm/storages/AbstractSplitsCacheAsync.js +1 -1
  145. package/esm/storages/AbstractSplitsCacheSync.js +1 -1
  146. package/esm/storages/KeyBuilder.js +12 -12
  147. package/esm/storages/KeyBuilderCS.js +12 -12
  148. package/esm/storages/KeyBuilderSS.js +14 -14
  149. package/esm/storages/getRolloutPlan.js +1 -1
  150. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
  151. package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
  152. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
  153. package/esm/storages/inMemory/TelemetryCacheInMemory.js +2 -2
  154. package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
  155. package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +4 -4
  156. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
  157. package/esm/storages/inRedis/RedisAdapter.js +7 -7
  158. package/esm/storages/inRedis/SplitsCacheInRedis.js +4 -4
  159. package/esm/storages/inRedis/TelemetryCacheInRedis.js +7 -7
  160. package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
  161. package/esm/storages/pluggable/EventsCachePluggable.js +1 -1
  162. package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +5 -5
  163. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
  164. package/esm/storages/pluggable/SplitsCachePluggable.js +2 -2
  165. package/esm/storages/pluggable/TelemetryCachePluggable.js +7 -7
  166. package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
  167. package/esm/storages/pluggable/index.js +2 -2
  168. package/esm/storages/pluggable/wrapperAdapter.js +1 -1
  169. package/esm/storages/setRolloutPlan.js +1 -1
  170. package/esm/storages/utils.js +6 -6
  171. package/esm/sync/offline/splitsParser/parseCondition.js +1 -1
  172. package/esm/sync/polling/fetchers/splitChangesFetcher.js +24 -15
  173. package/esm/sync/polling/pollingManagerCS.js +11 -11
  174. package/esm/sync/polling/pollingManagerSS.js +13 -13
  175. package/esm/sync/polling/syncTasks/definitionsSyncTask.js +8 -0
  176. package/esm/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
  177. package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  178. package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
  179. package/esm/sync/streaming/SSEClient/index.js +2 -2
  180. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
  181. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
  182. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
  183. package/esm/sync/streaming/parseUtils.js +10 -10
  184. package/esm/sync/streaming/pushManager.js +3 -3
  185. package/esm/sync/submitters/impressionsSubmitter.js +6 -6
  186. package/esm/sync/submitters/submitter.js +1 -1
  187. package/esm/sync/syncManagerOnline.js +5 -2
  188. package/esm/trackers/eventTracker.js +10 -12
  189. package/esm/trackers/impressionObserver/buildKey.js +1 -1
  190. package/esm/trackers/impressionsTracker.js +38 -21
  191. package/esm/trackers/uniqueKeysTracker.js +1 -1
  192. package/esm/utils/EventEmitter.js +387 -0
  193. package/esm/utils/filter/bloomFilter.js +33 -0
  194. package/esm/utils/inputValidation/apiKey.js +1 -1
  195. package/esm/utils/inputValidation/attribute.js +2 -2
  196. package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
  197. package/esm/utils/inputValidation/definitionExistence.js +15 -0
  198. package/esm/utils/inputValidation/definitions.js +21 -0
  199. package/esm/utils/inputValidation/index.js +3 -3
  200. package/esm/utils/inputValidation/isOperational.js +4 -4
  201. package/esm/utils/inputValidation/target.js +18 -0
  202. package/esm/utils/labels/index.js +2 -2
  203. package/esm/utils/promise/timeout.js +1 -1
  204. package/esm/utils/settingsValidation/splitFilters.js +4 -4
  205. package/esm/utils/settingsValidation/url.js +5 -5
  206. package/package.json +15 -6
  207. package/src/dtos/types.ts +65 -70
  208. package/src/evaluator/Engine.ts +4 -4
  209. package/src/evaluator/combiners/and.ts +3 -3
  210. package/src/evaluator/combiners/ifelseif.ts +2 -2
  211. package/src/evaluator/condition/engineUtils.ts +2 -2
  212. package/src/evaluator/condition/index.ts +3 -3
  213. package/src/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.ts +76 -0
  214. package/src/evaluator/fallbackConfigsCalculator/index.ts +24 -0
  215. package/src/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.ts +5 -7
  216. package/src/evaluator/fallbackTreatmentsCalculator/index.ts +27 -41
  217. package/src/evaluator/index.ts +80 -45
  218. package/src/evaluator/matchers/dependency.ts +2 -2
  219. package/src/evaluator/matchers/matcherTypes.ts +2 -2
  220. package/src/evaluator/matchers/prerequisites.ts +4 -4
  221. package/src/evaluator/matchers/rbsegment.ts +2 -2
  222. package/src/evaluator/matchers/whitelist.ts +2 -2
  223. package/src/evaluator/matchersTransform/index.ts +2 -2
  224. package/src/evaluator/matchersTransform/whitelist.ts +2 -2
  225. package/src/evaluator/parser/index.ts +4 -4
  226. package/src/evaluator/treatments/index.ts +2 -2
  227. package/src/evaluator/types.ts +6 -6
  228. package/src/evaluator/value/index.ts +1 -1
  229. package/src/integrations/pluggable.ts +1 -1
  230. package/src/listeners/browser.ts +11 -8
  231. package/src/listeners/node.ts +2 -5
  232. package/src/logger/constants.ts +11 -17
  233. package/src/logger/messages/debug.ts +5 -6
  234. package/src/logger/messages/error.ts +3 -3
  235. package/src/logger/messages/info.ts +1 -3
  236. package/src/logger/messages/warn.ts +8 -8
  237. package/src/platform/browser.ts +14 -0
  238. package/src/platform/getEventSource/browser.ts +4 -0
  239. package/src/platform/getEventSource/eventsource.js +519 -0
  240. package/src/platform/getEventSource/node.ts +23 -0
  241. package/src/platform/getFetch/browser.ts +5 -0
  242. package/src/platform/getFetch/node.ts +27 -0
  243. package/src/platform/getOptions/node.ts +24 -0
  244. package/src/platform/node.ts +16 -0
  245. package/src/readiness/constants.ts +1 -0
  246. package/src/sdkClient/client.ts +11 -41
  247. package/src/sdkClient/clientInputValidation.ts +44 -84
  248. package/src/sdkClient/sdkClient.ts +5 -54
  249. package/src/sdkClient/sdkLifecycle.ts +78 -0
  250. package/src/sdkClient/trackMethod.ts +59 -0
  251. package/src/sdkFactory/index.ts +10 -54
  252. package/src/sdkFactory/types.ts +19 -16
  253. package/src/sdkManager/index.ts +9 -9
  254. package/src/services/splitApi.ts +6 -0
  255. package/src/services/types.ts +3 -2
  256. package/src/storages/AbstractSplitsCacheAsync.ts +7 -7
  257. package/src/storages/AbstractSplitsCacheSync.ts +10 -10
  258. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +2 -2
  259. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +6 -6
  260. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +2 -2
  261. package/src/storages/inMemory/SplitsCacheInMemory.ts +5 -5
  262. package/src/storages/inMemory/TelemetryCacheInMemory.ts +2 -2
  263. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +2 -2
  264. package/src/storages/inRedis/SplitsCacheInRedis.ts +9 -9
  265. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +2 -2
  266. package/src/storages/pluggable/SplitsCachePluggable.ts +9 -9
  267. package/src/storages/types.ts +21 -16
  268. package/src/sync/offline/splitsParser/parseCondition.ts +2 -2
  269. package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +3 -3
  270. package/src/sync/offline/splitsParser/types.ts +6 -3
  271. package/src/sync/offline/syncManagerOffline.ts +2 -2
  272. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +6 -6
  273. package/src/sync/polling/fetchers/splitChangesFetcher.ts +57 -22
  274. package/src/sync/polling/fetchers/types.ts +5 -3
  275. package/src/sync/polling/pollingManagerCS.ts +12 -10
  276. package/src/sync/polling/pollingManagerSS.ts +15 -13
  277. package/src/sync/polling/syncTasks/{splitsSyncTask.ts → definitionsSyncTask.ts} +10 -11
  278. package/src/sync/polling/types.ts +3 -3
  279. package/src/sync/polling/updaters/{splitChangesUpdater.ts → definitionChangesUpdater.ts} +77 -68
  280. package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
  281. package/src/sync/polling/updaters/segmentChangesUpdater.ts +7 -7
  282. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +6 -6
  283. package/src/sync/streaming/parseUtils.ts +12 -12
  284. package/src/sync/streaming/pushManager.ts +3 -3
  285. package/src/sync/submitters/impressionsSubmitter.ts +9 -9
  286. package/src/sync/submitters/types.ts +3 -0
  287. package/src/sync/syncManagerOnline.ts +6 -2
  288. package/src/trackers/eventTracker.ts +7 -10
  289. package/src/trackers/impressionsTracker.ts +42 -26
  290. package/src/trackers/types.ts +3 -1
  291. package/src/utils/EventEmitter.js +444 -0
  292. package/src/utils/filter/bloomFilter.ts +38 -0
  293. package/src/utils/inputValidation/definition.ts +27 -0
  294. package/src/utils/inputValidation/definitionExistence.ts +19 -0
  295. package/src/utils/inputValidation/definitions.ts +21 -0
  296. package/src/utils/inputValidation/index.ts +3 -3
  297. package/src/utils/inputValidation/isOperational.ts +4 -4
  298. package/src/utils/inputValidation/target.ts +21 -0
  299. package/src/utils/labels/index.ts +2 -2
  300. package/src/utils/settingsValidation/splitFilters.ts +3 -3
  301. package/types/splitio.d.ts +202 -9
  302. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
  303. package/cjs/utils/inputValidation/splits.js +0 -25
  304. package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
  305. package/esm/utils/inputValidation/splitExistence.js +0 -15
  306. package/esm/utils/inputValidation/splits.js +0 -21
  307. package/src/utils/inputValidation/split.ts +0 -27
  308. package/src/utils/inputValidation/splitExistence.ts +0 -19
  309. package/src/utils/inputValidation/splits.ts +0 -21
@@ -1,17 +1,17 @@
1
1
  import { evaluateFeature, evaluateFeatures, evaluateFeaturesByFlagSets } from '../evaluator';
2
2
  import { thenable } from '../utils/promise/thenable';
3
3
  import { getMatching, getBucketing } from '../utils/key';
4
- import { validateSplitExistence } from '../utils/inputValidation/splitExistence';
5
- import { validateTrafficTypeExistence } from '../utils/inputValidation/trafficTypeExistence';
4
+ import { validateDefinitionExistence } from '../utils/inputValidation/definitionExistence';
6
5
  import { SDK_NOT_READY } from '../utils/labels';
7
- import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TRACK, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, TREATMENTS_BY_FLAGSETS, TREATMENTS_BY_FLAGSET, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENT_WITH_CONFIG, GET_TREATMENT, GET_TREATMENTS, TRACK_FN_LABEL } from '../utils/constants';
6
+ import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, TREATMENTS_BY_FLAGSETS, TREATMENTS_BY_FLAGSET, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENT_WITH_CONFIG, GET_TREATMENT, GET_TREATMENTS } from '../utils/constants';
8
7
  import { IEvaluationResult } from '../evaluator/types';
9
8
  import SplitIO from '../../types/splitio';
10
- import { IMPRESSION, IMPRESSION_QUEUEING } from '../logger/constants';
9
+ import { IMPRESSION_QUEUEING } from '../logger/constants';
11
10
  import { ISdkFactoryContext } from '../sdkFactory/types';
12
11
  import { isConsumerMode } from '../utils/settingsValidation/mode';
13
12
  import { Method } from '../sync/submitters/types';
14
13
  import { ImpressionDecorated } from '../trackers/types';
14
+ import { trackMethodFactory } from './trackMethod';
15
15
 
16
16
  const treatmentNotReady = { treatment: CONTROL, label: SDK_NOT_READY };
17
17
 
@@ -23,7 +23,7 @@ function treatmentsNotReady(featureFlagNames: string[]) {
23
23
  return evaluations;
24
24
  }
25
25
 
26
- function stringify(options?: SplitIO.EvaluationOptions) {
26
+ export function stringify(options?: SplitIO.EvaluationOptions) {
27
27
  if (options && options.properties) {
28
28
  try {
29
29
  return JSON.stringify(options.properties);
@@ -35,7 +35,7 @@ function stringify(options?: SplitIO.EvaluationOptions) {
35
35
  * Creator of base client with getTreatments and track methods.
36
36
  */
37
37
  export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | SplitIO.IAsyncClient {
38
- const { sdkReadinessManager: { readinessManager }, storage, settings, impressionsTracker, eventTracker, telemetryTracker, fallbackTreatmentsCalculator } = params;
38
+ const { sdkReadinessManager: { readinessManager }, storage, settings, impressionsTracker, telemetryTracker, fallbackCalculator } = params;
39
39
  const { log, mode } = settings;
40
40
  const isAsync = isConsumerMode(mode);
41
41
 
@@ -147,16 +147,14 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
147
147
  let { treatment, label, config = null } = evaluation;
148
148
 
149
149
  if (treatment === CONTROL) {
150
- const fallbackTreatment = fallbackTreatmentsCalculator.resolve(featureFlagName, label);
150
+ const fallbackTreatment = fallbackCalculator(featureFlagName, label);
151
151
  treatment = fallbackTreatment.treatment;
152
152
  label = fallbackTreatment.label;
153
153
  config = fallbackTreatment.config;
154
154
  }
155
155
 
156
- log.info(IMPRESSION, [featureFlagName, matchingKey, treatment, label]);
157
-
158
- if (validateSplitExistence(log, readinessManager, featureFlagName, label, invokingMethodName)) {
159
- log.info(IMPRESSION_QUEUEING);
156
+ if (validateDefinitionExistence(log, readinessManager, featureFlagName, label, invokingMethodName)) {
157
+ log.info(IMPRESSION_QUEUEING, ['Feature flag', featureFlagName, matchingKey, treatment, label]);
160
158
  queue.push({
161
159
  imp: {
162
160
  feature: featureFlagName,
@@ -175,42 +173,14 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
175
173
  if (withConfig) {
176
174
  return {
177
175
  treatment,
178
- config
176
+ config: config as string | null
179
177
  };
180
178
  }
181
179
 
182
180
  return treatment;
183
181
  }
184
182
 
185
- function track(key: SplitIO.SplitKey, trafficTypeName: string, eventTypeId: string, value?: number, properties?: SplitIO.Properties, size = 1024) {
186
- const stopTelemetryTracker = telemetryTracker.trackEval(TRACK);
187
-
188
- const matchingKey = getMatching(key);
189
- const timestamp = Date.now();
190
- const eventData: SplitIO.EventData = {
191
- eventTypeId,
192
- trafficTypeName,
193
- value,
194
- timestamp,
195
- key: matchingKey,
196
- properties
197
- };
198
-
199
- // This may be async but we only warn, we don't actually care if it is valid or not in terms of queueing the event.
200
- validateTrafficTypeExistence(log, readinessManager, storage.splits, mode, trafficTypeName, TRACK_FN_LABEL);
201
-
202
- const result = eventTracker.track(eventData, size);
203
-
204
- if (thenable(result)) {
205
- return result.then((result) => {
206
- stopTelemetryTracker();
207
- return result;
208
- });
209
- } else {
210
- stopTelemetryTracker();
211
- return result;
212
- }
213
- }
183
+ const track = trackMethodFactory(params);
214
184
 
215
185
  return {
216
186
  getTreatment,
@@ -1,31 +1,27 @@
1
1
  import {
2
2
  validateAttributes,
3
- validateEvent,
4
- validateEventValue,
5
- validateEventProperties,
6
3
  validateKey,
7
- validateSplit,
8
- validateSplits,
9
- validateTrafficType,
4
+ validateDefinition,
5
+ validateDefinitions,
10
6
  validateIfNotDestroyed,
11
7
  validateIfReadyFromCache,
12
8
  validateEvaluationOptions
13
9
  } from '../utils/inputValidation';
14
10
  import { startsWith } from '../utils/lang';
15
- import { GET_TREATMENT, GET_TREATMENTS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENT_WITH_CONFIG, TRACK_FN_LABEL } from '../utils/constants';
11
+ import { GET_TREATMENT, GET_TREATMENTS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENT_WITH_CONFIG } from '../utils/constants';
16
12
  import { IReadinessManager } from '../readiness/types';
17
13
  import { MaybeThenable } from '../dtos/types';
18
14
  import { ISettings } from '../types';
19
15
  import SplitIO from '../../types/splitio';
20
16
  import { isConsumerMode } from '../utils/settingsValidation/mode';
21
17
  import { validateFlagSets } from '../utils/settingsValidation/splitFilters';
22
- import { IFallbackTreatmentsCalculator } from '../evaluator/fallbackTreatmentsCalculator';
18
+ import { IFallbackCalculator } from '../evaluator/fallbackTreatmentsCalculator';
23
19
 
24
20
  /**
25
21
  * Decorator that validates the input before actually executing the client methods.
26
22
  * We should "guard" the client here, while not polluting the "real" implementation of those methods.
27
23
  */
28
- export function clientInputValidationDecorator<TClient extends SplitIO.IClient | SplitIO.IAsyncClient>(settings: ISettings, client: TClient, readinessManager: IReadinessManager, fallbackTreatmentsCalculator: IFallbackTreatmentsCalculator): TClient {
24
+ export function clientInputValidationDecorator<TClient extends SplitIO.IClient | SplitIO.IAsyncClient>(settings: ISettings, client: TClient, readinessManager: IReadinessManager, fallbackCalculator: IFallbackCalculator): TClient {
29
25
 
30
26
  const { log, mode } = settings;
31
27
  const isAsync = isConsumerMode(mode);
@@ -39,14 +35,14 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
39
35
  const nameOrNames = methodName.indexOf('ByFlagSet') > -1 ?
40
36
  validateFlagSets(log, methodName, maybeNameOrNames as string[], settings.sync.__splitFiltersValidation.groupedFilters.bySet) :
41
37
  startsWith(methodName, GET_TREATMENTS) ?
42
- validateSplits(log, maybeNameOrNames, methodName) :
43
- validateSplit(log, maybeNameOrNames, methodName);
38
+ validateDefinitions(log, maybeNameOrNames, methodName) :
39
+ validateDefinition(log, maybeNameOrNames, methodName);
44
40
 
45
41
  const attributes = validateAttributes(log, maybeAttributes, methodName);
46
42
  const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, methodName);
47
43
  const options = validateEvaluationOptions(log, maybeOptions, methodName);
48
44
 
49
- validateIfReadyFromCache(log, readinessManager, methodName, nameOrNames);
45
+ validateIfReadyFromCache(log, readinessManager, methodName);
50
46
 
51
47
  const valid = isNotDestroyed && key && nameOrNames && attributes !== false;
52
48
 
@@ -59,17 +55,20 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
59
55
  };
60
56
  }
61
57
 
62
- function evaluateFallBackTreatment(featureFlagName: string, withConfig: boolean): SplitIO.Treatment | SplitIO.TreatmentWithConfig {
63
- const { treatment, config } = fallbackTreatmentsCalculator.resolve(featureFlagName, '');
58
+ function evaluateFallBackTreatment(featureFlagName: string | false | string[], withConfig: boolean) {
59
+ if (Array.isArray(featureFlagName)) {
60
+ const res: SplitIO.Treatments = {};
61
+ featureFlagName.forEach((split: string) => res[split] = evaluateFallBackTreatment(split, withConfig) as SplitIO.Treatment);
62
+ return res;
63
+ }
64
+
65
+ const { treatment, config } = fallbackCalculator(featureFlagName as string);
64
66
 
65
- if (withConfig) {
66
- return {
67
+ return withConfig ?
68
+ {
67
69
  treatment,
68
70
  config
69
- };
70
- }
71
-
72
- return treatment;
71
+ } : treatment;
73
72
  }
74
73
 
75
74
  function wrapResult<T>(value: T): MaybeThenable<T> {
@@ -79,104 +78,65 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
79
78
  function getTreatment(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
80
79
  const params = validateEvaluationParams(GET_TREATMENT, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
81
80
 
82
- if (params.valid) {
83
- return client.getTreatment(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options);
84
- } else {
85
- const result = evaluateFallBackTreatment(params.nameOrNames as string, false);
86
- return wrapResult(result);
87
- }
81
+ return params.valid ?
82
+ client.getTreatment(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options) :
83
+ wrapResult(evaluateFallBackTreatment(params.nameOrNames, false));
88
84
  }
89
85
 
90
86
  function getTreatmentWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
91
87
  const params = validateEvaluationParams(GET_TREATMENT_WITH_CONFIG, maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions);
92
88
 
93
- if (params.valid) {
94
- return client.getTreatmentWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options);
95
- } else {
96
- const result = evaluateFallBackTreatment(params.nameOrNames as string, true);
97
- return wrapResult(result);
98
- }
89
+ return params.valid ?
90
+ client.getTreatmentWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string, params.attributes as SplitIO.Attributes | undefined, params.options) :
91
+ wrapResult(evaluateFallBackTreatment(params.nameOrNames, true));
99
92
  }
100
93
 
101
94
  function getTreatments(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
102
95
  const params = validateEvaluationParams(GET_TREATMENTS, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
103
96
 
104
- if (params.valid) {
105
- return client.getTreatments(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
106
- } else {
107
- const res: SplitIO.Treatments = {};
108
- if (params.nameOrNames) (params.nameOrNames as string[]).forEach((split: string) => res[split] = evaluateFallBackTreatment(split, false) as SplitIO.Treatment);
109
-
110
- return wrapResult(res);
111
- }
97
+ return params.valid ?
98
+ client.getTreatments(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
99
+ wrapResult(evaluateFallBackTreatment(params.nameOrNames || [], false));
112
100
  }
113
101
 
114
102
  function getTreatmentsWithConfig(maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
115
103
  const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG, maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions);
116
104
 
117
- if (params.valid) {
118
- return client.getTreatmentsWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
119
- } else {
120
- const res: SplitIO.TreatmentsWithConfig = {};
121
- if (params.nameOrNames) (params.nameOrNames as string[]).forEach(split => res[split] = evaluateFallBackTreatment(split, true) as SplitIO.TreatmentWithConfig);
122
-
123
- return wrapResult(res);
124
- }
105
+ return params.valid ?
106
+ client.getTreatmentsWithConfig(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
107
+ wrapResult(evaluateFallBackTreatment(params.nameOrNames || [], true));
125
108
  }
126
109
 
127
110
  function getTreatmentsByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
128
111
  const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
129
112
 
130
- if (params.valid) {
131
- return client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
132
- } else {
133
- return wrapResult({});
134
- }
113
+ return params.valid ?
114
+ client.getTreatmentsByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
115
+ wrapResult({});
135
116
  }
136
117
 
137
118
  function getTreatmentsWithConfigByFlagSets(maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
138
119
  const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, maybeKey, maybeFlagSets, maybeAttributes, maybeOptions);
139
120
 
140
- if (params.valid) {
141
- return client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options);
142
- } else {
143
- return wrapResult({});
144
- }
121
+ return params.valid ?
122
+ client.getTreatmentsWithConfigByFlagSets(params.key as SplitIO.SplitKey, params.nameOrNames as string[], params.attributes as SplitIO.Attributes | undefined, params.options) :
123
+ wrapResult({});
145
124
  }
146
125
 
147
126
  function getTreatmentsByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
148
127
  const params = validateEvaluationParams(GET_TREATMENTS_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
149
128
 
150
- if (params.valid) {
151
- return client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options);
152
- } else {
153
- return wrapResult({});
154
- }
129
+ return params.valid ?
130
+ client.getTreatmentsByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options) :
131
+ wrapResult({});
155
132
  }
156
133
 
157
134
  function getTreatmentsWithConfigByFlagSet(maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes, maybeOptions?: SplitIO.EvaluationOptions) {
158
135
  const params = validateEvaluationParams(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, maybeKey, [maybeFlagSet], maybeAttributes, maybeOptions);
159
136
 
160
- if (params.valid) {
161
- return client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options);
162
- } else {
163
- return wrapResult({});
164
- }
165
- }
166
-
167
- function track(maybeKey: SplitIO.SplitKey, maybeTT: string, maybeEvent: string, maybeEventValue?: number, maybeProperties?: SplitIO.Properties) {
168
- const key = validateKey(log, maybeKey, TRACK_FN_LABEL);
169
- const tt = validateTrafficType(log, maybeTT, TRACK_FN_LABEL);
170
- const event = validateEvent(log, maybeEvent, TRACK_FN_LABEL);
171
- const eventValue = validateEventValue(log, maybeEventValue, TRACK_FN_LABEL);
172
- const { properties, size } = validateEventProperties(log, maybeProperties, TRACK_FN_LABEL);
173
- const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, TRACK_FN_LABEL);
174
-
175
- if (isNotDestroyed && key && tt && event && eventValue !== false && properties !== false) { // @ts-expect-error
176
- return client.track(key, tt, event, eventValue, properties, size);
177
- } else {
178
- return isAsync ? Promise.resolve(false) : false;
179
- }
137
+ return params.valid ?
138
+ client.getTreatmentsWithConfigByFlagSet(params.key as SplitIO.SplitKey, (params.nameOrNames as string[])[0], params.attributes as SplitIO.Attributes | undefined, params.options) :
139
+ wrapResult({});
180
140
  }
181
141
 
182
142
  return {
@@ -188,6 +148,6 @@ export function clientInputValidationDecorator<TClient extends SplitIO.IClient |
188
148
  getTreatmentsWithConfigByFlagSets,
189
149
  getTreatmentsByFlagSet,
190
150
  getTreatmentsWithConfigByFlagSet,
191
- track
151
+ track: client.track,
192
152
  } as TClient;
193
153
  }
@@ -1,39 +1,16 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import SplitIO from '../../types/splitio';
3
- import { releaseApiKey } from '../utils/inputValidation/apiKey';
4
3
  import { clientFactory } from './client';
5
4
  import { clientInputValidationDecorator } from './clientInputValidation';
6
5
  import { ISdkFactoryContext } from '../sdkFactory/types';
7
-
8
- const COOLDOWN_TIME_IN_MILLIS = 1000;
6
+ import { sdkLifecycleFactory } from './sdkLifecycle';
9
7
 
10
8
  /**
11
- * Creates an Sdk client, i.e., a base client with status and destroy interface
9
+ * Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface
12
10
  */
13
11
  export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: boolean): SplitIO.IClient | SplitIO.IAsyncClient {
14
- const { sdkReadinessManager, syncManager, storage, signalListener, settings, telemetryTracker, uniqueKeysTracker } = params;
15
-
16
- let lastActionTime = 0;
17
-
18
- function __cooldown(func: Function, time: number) {
19
- const now = Date.now();
20
- //get the actual time elapsed in ms
21
- const timeElapsed = now - lastActionTime;
22
- //check if the time elapsed is less than desired cooldown
23
- if (timeElapsed < time) {
24
- //if yes, return message with remaining time in seconds
25
- settings.log.warn(`Flush cooldown, remaining time ${(time - timeElapsed) / 1000} seconds`);
26
- return Promise.resolve();
27
- } else {
28
- //Do the requested action and re-assign the lastActionTime
29
- lastActionTime = now;
30
- return func();
31
- }
32
- }
12
+ const { sdkReadinessManager, settings } = params;
33
13
 
34
- function __flush() {
35
- return syncManager ? syncManager.flush() : Promise.resolve();
36
- }
37
14
 
38
15
  return objectAssign(
39
16
  // Proto-linkage of the readiness Event Emitter
@@ -44,35 +21,9 @@ export function sdkClientFactory(params: ISdkFactoryContext, isSharedClient?: bo
44
21
  settings,
45
22
  clientFactory(params),
46
23
  sdkReadinessManager.readinessManager,
47
- params.fallbackTreatmentsCalculator
24
+ params.fallbackCalculator
48
25
  ),
49
26
 
50
- // Sdk destroy
51
- {
52
- flush() {
53
- // @TODO define cooldown time
54
- return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
55
- },
56
- destroy() {
57
- // Mark the SDK as destroyed immediately
58
- sdkReadinessManager.readinessManager.destroy();
59
-
60
- // For main client, cleanup the SDK Key, listeners and scheduled jobs, and record stat before flushing data
61
- if (!isSharedClient) {
62
- releaseApiKey(settings.core.authorizationKey);
63
- telemetryTracker.sessionLength();
64
- signalListener && signalListener.stop();
65
- uniqueKeysTracker.stop();
66
- }
67
-
68
- // Stop background jobs
69
- syncManager && syncManager.stop();
70
-
71
- return __flush().then(() => {
72
- // Cleanup storage
73
- return storage.destroy();
74
- });
75
- }
76
- }
27
+ sdkLifecycleFactory(params, isSharedClient)
77
28
  );
78
29
  }
@@ -0,0 +1,78 @@
1
+ import { releaseApiKey, validateAndTrackApiKey } from '../utils/inputValidation/apiKey';
2
+ import { ISdkFactoryContext } from '../sdkFactory/types';
3
+
4
+ const COOLDOWN_TIME_IN_MILLIS = 1000;
5
+
6
+ /**
7
+ * Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface
8
+ */
9
+ export function sdkLifecycleFactory(params: ISdkFactoryContext, isSharedClient?: boolean): { init(): void; flush(): Promise<void>; destroy(): Promise<void> } {
10
+ const { sdkReadinessManager, syncManager, storage, settings, telemetryTracker, impressionsTracker, platform } = params;
11
+
12
+ let hasInit = false;
13
+ let lastActionTime = 0;
14
+
15
+ const signalListener = platform.SignalListener && new platform.SignalListener(params);
16
+
17
+ function __cooldown(func: Function, time: number) {
18
+ const now = Date.now();
19
+ //get the actual time elapsed in ms
20
+ const timeElapsed = now - lastActionTime;
21
+ //check if the time elapsed is less than desired cooldown
22
+ if (timeElapsed < time) {
23
+ //if yes, return message with remaining time in seconds
24
+ settings.log.warn(`Flush cooldown, remaining time ${(time - timeElapsed) / 1000} seconds`);
25
+ return Promise.resolve();
26
+ } else {
27
+ //Do the requested action and re-assign the lastActionTime
28
+ lastActionTime = now;
29
+ return func();
30
+ }
31
+ }
32
+
33
+ function __flush() {
34
+ return syncManager ? syncManager.flush() : Promise.resolve();
35
+ }
36
+
37
+ return {
38
+ init() {
39
+ if (hasInit) return;
40
+ hasInit = true;
41
+
42
+ if (!isSharedClient) {
43
+ validateAndTrackApiKey(settings.log, settings.core.authorizationKey);
44
+ sdkReadinessManager.readinessManager.init();
45
+ impressionsTracker.start();
46
+ syncManager && syncManager.start();
47
+ signalListener && signalListener.start();
48
+ }
49
+ },
50
+
51
+ flush() {
52
+ // @TODO define cooldown time
53
+ return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
54
+ },
55
+
56
+ destroy() {
57
+ hasInit = false;
58
+ // Mark the SDK as destroyed immediately
59
+ sdkReadinessManager.readinessManager.destroy();
60
+
61
+ // For main client, cleanup the SDK Key, listeners and scheduled jobs, and record stat before flushing data
62
+ if (!isSharedClient) {
63
+ releaseApiKey(settings.core.authorizationKey);
64
+ telemetryTracker.sessionLength();
65
+ signalListener && signalListener.stop();
66
+ impressionsTracker.stop();
67
+ }
68
+
69
+ // Stop background jobs
70
+ syncManager && syncManager.stop();
71
+
72
+ return __flush().then(() => {
73
+ // Cleanup storage
74
+ return storage.destroy();
75
+ });
76
+ }
77
+ };
78
+ }
@@ -0,0 +1,59 @@
1
+ import { thenable } from '../utils/promise/thenable';
2
+ import { getMatching } from '../utils/key';
3
+ import { validateTrafficTypeExistence } from '../utils/inputValidation/trafficTypeExistence';
4
+ import { validateKey, validateTrafficType, validateEvent, validateEventValue, validateEventProperties, validateIfNotDestroyed } from '../utils/inputValidation';
5
+ import { TRACK, TRACK_FN_LABEL } from '../utils/constants';
6
+ import { isConsumerMode } from '../utils/settingsValidation/mode';
7
+ import SplitIO from '../../types/splitio';
8
+ import { ISdkFactoryContext } from '../sdkFactory/types';
9
+
10
+ /**
11
+ * Creates a standalone `track` function with input validation.
12
+ * Reusable by FF SDK client, Configs SDK, and thin-client SDK.
13
+ */
14
+ export function trackMethodFactory(params: Pick<ISdkFactoryContext, 'settings' | 'eventTracker' | 'telemetryTracker' | 'storage' | 'sdkReadinessManager'>, warnTTExistence = true) {
15
+ const { settings, storage: { splits }, telemetryTracker, eventTracker, sdkReadinessManager: { readinessManager } } = params;
16
+ const { log, mode } = settings;
17
+ const isAsync = isConsumerMode(mode);
18
+
19
+ return function track(maybeKey: SplitIO.SplitKey, maybeTT: string, maybeEvent: string, maybeEventValue?: number, maybeProperties?: SplitIO.Properties) {
20
+ // Input validation
21
+ const key = validateKey(log, maybeKey, TRACK_FN_LABEL);
22
+ const trafficTypeName = validateTrafficType(log, maybeTT, TRACK_FN_LABEL);
23
+ const eventTypeId = validateEvent(log, maybeEvent, TRACK_FN_LABEL);
24
+ const value = validateEventValue(log, maybeEventValue, TRACK_FN_LABEL);
25
+ const { properties, size } = validateEventProperties(log, maybeProperties, TRACK_FN_LABEL);
26
+ const isNotDestroyed = validateIfNotDestroyed(log, readinessManager, TRACK_FN_LABEL);
27
+
28
+ if (!(isNotDestroyed && key && trafficTypeName && eventTypeId && value !== false && properties !== false)) {
29
+ return isAsync ? Promise.resolve(false) : false;
30
+ }
31
+
32
+ // Core logic
33
+ const stopTelemetryTracker = telemetryTracker.trackEval(TRACK);
34
+
35
+ const eventData: SplitIO.EventData = {
36
+ eventTypeId,
37
+ trafficTypeName,
38
+ value,
39
+ timestamp: Date.now(),
40
+ key: getMatching(key),
41
+ properties: properties as SplitIO.Properties | undefined
42
+ };
43
+
44
+ // This may be async but we only warn, we don't actually care if it is valid or not in terms of queueing the event.
45
+ if (warnTTExistence) validateTrafficTypeExistence(log, readinessManager, splits, mode, trafficTypeName, TRACK_FN_LABEL);
46
+
47
+ const result = eventTracker.track(eventData, size);
48
+
49
+ if (thenable(result)) {
50
+ return result.then((result) => {
51
+ stopTelemetryTracker();
52
+ return result;
53
+ });
54
+ } else {
55
+ stopTelemetryTracker();
56
+ return result;
57
+ }
58
+ };
59
+ }