@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
@@ -3,7 +3,9 @@ import { IPostEventsBulk } from '../../services/types';
3
3
  import { ISyncTask, ITimeTracker } from '../types';
4
4
  import { submitterSyncTaskFactory } from './submitterSyncTask';
5
5
  import { ILogger } from '../../logger/types';
6
- import { SUBMITTERS_PUSH_FULL_EVENTS_QUEUE } from '../../logger/constants';
6
+ import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
7
+
8
+ const DATA_NAME = 'events';
7
9
 
8
10
  /**
9
11
  * Sync task that periodically posts tracked events
@@ -18,26 +20,37 @@ export function eventsSyncTaskFactory(
18
20
  ): ISyncTask {
19
21
 
20
22
  // don't retry events.
21
- const syncTask = submitterSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate, 'queued events', latencyTracker);
23
+ const syncTask = submitterSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate, DATA_NAME, latencyTracker);
22
24
 
23
- // Set a timer for the first push of events,
25
+ // Set a timer for the first push window of events.
26
+ // Not implemented in the base submitter or sync task, since this feature is only used by the events submitter.
24
27
  if (eventsFirstPushWindow > 0) {
28
+ let running = false;
25
29
  let stopEventPublisherTimeout: ReturnType<typeof setTimeout>;
26
30
  const originalStart = syncTask.start;
27
31
  syncTask.start = () => {
32
+ running = true;
28
33
  stopEventPublisherTimeout = setTimeout(originalStart, eventsFirstPushWindow);
29
34
  };
30
35
  const originalStop = syncTask.stop;
31
36
  syncTask.stop = () => {
37
+ running = false;
32
38
  clearTimeout(stopEventPublisherTimeout);
33
39
  originalStop();
34
40
  };
41
+ syncTask.isRunning = () => {
42
+ return running;
43
+ };
35
44
  }
36
45
 
37
- // register eventsSubmitter to be executed when events cache is full
46
+ // register events submitter to be executed when events cache is full
38
47
  eventsCache.setOnFullQueueCb(() => {
39
- log.info(SUBMITTERS_PUSH_FULL_EVENTS_QUEUE);
40
- syncTask.execute();
48
+ if (syncTask.isRunning()) {
49
+ log.info(SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
50
+ syncTask.execute();
51
+ }
52
+ // If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
53
+ // Data will be sent when submitter is resumed.
41
54
  });
42
55
 
43
56
  return syncTask;
@@ -6,6 +6,9 @@ import { ImpressionDTO } from '../../types';
6
6
  import { submitterSyncTaskFactory } from './submitterSyncTask';
7
7
  import { ImpressionsPayload } from './types';
8
8
  import { ILogger } from '../../logger/types';
9
+ import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
10
+
11
+ const DATA_NAME = 'impressions';
9
12
 
10
13
  /**
11
14
  * Converts `impressions` data from cache into request payload.
@@ -50,5 +53,17 @@ export function impressionsSyncTaskFactory(
50
53
  ): ISyncTask {
51
54
 
52
55
  // retry impressions only once.
53
- return submitterSyncTaskFactory(log, postTestImpressionsBulk, impressionsCache, impressionsRefreshRate, 'impressions', latencyTracker, fromImpressionsCollector.bind(undefined, sendLabels), 1);
56
+ const syncTask = submitterSyncTaskFactory(log, postTestImpressionsBulk, impressionsCache, impressionsRefreshRate, DATA_NAME, latencyTracker, fromImpressionsCollector.bind(undefined, sendLabels), 1);
57
+
58
+ // register impressions submitter to be executed when impressions cache is full
59
+ impressionsCache.setOnFullQueueCb(() => {
60
+ if (syncTask.isRunning()) {
61
+ log.info(SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
62
+ syncTask.execute();
63
+ }
64
+ // If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
65
+ // Data will be sent when submitter is resumed.
66
+ });
67
+
68
+ return syncTask;
54
69
  }
@@ -6,6 +6,7 @@ import { IPushManager } from './streaming/types';
6
6
  import { IPollingManager, IPollingManagerCS } from './polling/types';
7
7
  import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
8
8
  import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
9
+ import { isConsentGranted } from '../consent';
9
10
 
10
11
  /**
11
12
  * Online SyncManager factory.
@@ -25,7 +26,7 @@ export function syncManagerOnlineFactory(
25
26
  */
26
27
  return function (params: ISyncManagerFactoryParams): ISyncManagerCS {
27
28
 
28
- const { log, streamingEnabled } = params.settings;
29
+ const { settings, settings: { log, streamingEnabled } } = params;
29
30
 
30
31
  /** Polling Manager */
31
32
  const pollingManager = pollingManagerFactory && pollingManagerFactory(params);
@@ -39,7 +40,6 @@ export function syncManagerOnlineFactory(
39
40
  // It is not inyected as push and polling managers, because at the moment it is required
40
41
  const submitter = submitterManagerFactory(params);
41
42
 
42
-
43
43
  /** Sync Manager logic */
44
44
 
45
45
  function startPolling() {
@@ -69,12 +69,18 @@ export function syncManagerOnlineFactory(
69
69
  let startFirstTime = true; // flag to distinguish calling the `start` method for the first time, to support pausing and resuming the synchronization
70
70
 
71
71
  return {
72
+ // Exposed for fine-grained control of synchronization.
73
+ // E.g.: user consent, app state changes (Page hide, Foreground/Background, Online/Offline).
74
+ pollingManager,
72
75
  pushManager,
76
+ submitter,
73
77
 
74
78
  /**
75
79
  * Method used to start the syncManager for the first time, or resume it after being stopped.
76
80
  */
77
81
  start() {
82
+ running = true;
83
+
78
84
  // start syncing splits and segments
79
85
  if (pollingManager) {
80
86
  if (pushManager) {
@@ -90,21 +96,21 @@ export function syncManagerOnlineFactory(
90
96
  }
91
97
 
92
98
  // start periodic data recording (events, impressions, telemetry).
93
- if (submitter) submitter.start();
94
- running = true;
99
+ if (isConsentGranted(settings)) submitter.start();
95
100
  },
96
101
 
97
102
  /**
98
103
  * Method used to stop/pause the syncManager.
99
104
  */
100
105
  stop() {
106
+ running = false;
107
+
101
108
  // stop syncing
102
109
  if (pushManager) pushManager.stop();
103
110
  if (pollingManager && pollingManager.isRunning()) pollingManager.stop();
104
111
 
105
112
  // stop periodic data recording (events, impressions, telemetry).
106
- if (submitter) submitter.stop();
107
- running = false;
113
+ submitter.stop();
108
114
  },
109
115
 
110
116
  isRunning() {
@@ -112,7 +118,7 @@ export function syncManagerOnlineFactory(
112
118
  },
113
119
 
114
120
  flush() {
115
- if (submitter) return submitter.execute();
121
+ if (isConsentGranted(settings)) return submitter.execute();
116
122
  else return Promise.resolve();
117
123
  },
118
124
 
package/src/sync/types.ts CHANGED
@@ -3,6 +3,7 @@ import { IPlatform } from '../sdkFactory/types';
3
3
  import { ISplitApi } from '../services/types';
4
4
  import { IStorageSync } from '../storages/types';
5
5
  import { ISettings } from '../types';
6
+ import { IPollingManager } from './polling/types';
6
7
  import { IPushManager } from './streaming/types';
7
8
 
8
9
  export interface ITask<Input extends any[] = []> {
@@ -43,7 +44,9 @@ export interface ITimeTracker {
43
44
 
44
45
  export interface ISyncManager extends ITask {
45
46
  flush(): Promise<any>,
46
- pushManager?: IPushManager
47
+ pushManager?: IPushManager,
48
+ pollingManager?: IPollingManager,
49
+ submitter?: ISyncTask
47
50
  }
48
51
 
49
52
  export interface ISyncManagerCS extends ISyncManager {
@@ -2,9 +2,10 @@ import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import { thenable } from '../utils/promise/thenable';
3
3
  import { IEventsCacheBase } from '../storages/types';
4
4
  import { IEventsHandler, IEventTracker } from './types';
5
- import { SplitIO } from '../types';
6
- import { ILogger } from '../logger/types';
5
+ import { ISettings, SplitIO } from '../types';
7
6
  import { EVENTS_TRACKER_SUCCESS, ERROR_EVENTS_TRACKER } from '../logger/constants';
7
+ import { CONSENT_DECLINED } from '../utils/constants';
8
+ import { isStorageSync } from './impressionObserver/utils';
8
9
 
9
10
  /**
10
11
  * Event tracker stores events in cache and pass them to the integrations manager if provided.
@@ -13,11 +14,14 @@ import { EVENTS_TRACKER_SUCCESS, ERROR_EVENTS_TRACKER } from '../logger/constant
13
14
  * @param integrationsManager optional event handler used for integrations
14
15
  */
15
16
  export function eventTrackerFactory(
16
- log: ILogger,
17
+ settings: ISettings,
17
18
  eventsCache: IEventsCacheBase,
18
19
  integrationsManager?: IEventsHandler
19
20
  ): IEventTracker {
20
21
 
22
+ const log = settings.log;
23
+ const isSync = isStorageSync(settings);
24
+
21
25
  function queueEventsCallback(eventData: SplitIO.EventData, tracked: boolean) {
22
26
  const { eventTypeId, trafficTypeName, key, value, timestamp, properties } = eventData;
23
27
  // Logging every prop would be too much.
@@ -44,6 +48,10 @@ export function eventTrackerFactory(
44
48
 
45
49
  return {
46
50
  track(eventData: SplitIO.EventData, size?: number) {
51
+ if (settings.userConsent === CONSENT_DECLINED) {
52
+ return isSync ? false : Promise.resolve(false);
53
+ }
54
+
47
55
  const tracked = eventsCache.track(eventData, size);
48
56
 
49
57
  if (thenable(tracked)) {
@@ -1,4 +1,4 @@
1
- import { CONSUMER_PARTIAL_MODE, OPTIMIZED, PRODUCER_MODE, STANDALONE_MODE } from '../../utils/constants';
1
+ import { CONSUMER_MODE, CONSUMER_PARTIAL_MODE, OPTIMIZED, PRODUCER_MODE, STANDALONE_MODE } from '../../utils/constants';
2
2
  import { ISettings } from '../../types';
3
3
 
4
4
  /**
@@ -15,3 +15,10 @@ export function shouldBeOptimized(settings: ISettings) {
15
15
  if (!shouldAddPt(settings)) return false;
16
16
  return settings.sync.impressionsMode === OPTIMIZED ? true : false;
17
17
  }
18
+
19
+ /**
20
+ * Storage is async if mode is consumer or partial consumer
21
+ */
22
+ export function isStorageSync(settings: ISettings) {
23
+ return [CONSUMER_MODE, CONSUMER_PARTIAL_MODE].indexOf(settings.mode) === -1 ? true : false;
24
+ }
@@ -5,8 +5,8 @@ import { IImpressionCountsCacheSync, IImpressionsCacheBase } from '../storages/t
5
5
  import { IImpressionsHandler, IImpressionsTracker } from './types';
6
6
  import { SplitIO, ImpressionDTO, ISettings } from '../types';
7
7
  import { IImpressionObserver } from './impressionObserver/types';
8
- import { ILogger } from '../logger/types';
9
8
  import { IMPRESSIONS_TRACKER_SUCCESS, ERROR_IMPRESSIONS_TRACKER, ERROR_IMPRESSIONS_LISTENER } from '../logger/constants';
9
+ import { CONSENT_DECLINED } from '../utils/constants';
10
10
 
11
11
  /**
12
12
  * Impressions tracker stores impressions in cache and pass them to the listener and integrations manager if provided.
@@ -19,22 +19,21 @@ import { IMPRESSIONS_TRACKER_SUCCESS, ERROR_IMPRESSIONS_TRACKER, ERROR_IMPRESSIO
19
19
  * @param countsCache optional cache to save impressions count. If provided, impressions will be deduped (OPTIMIZED mode)
20
20
  */
21
21
  export function impressionsTrackerFactory(
22
- log: ILogger,
22
+ settings: ISettings,
23
23
  impressionsCache: IImpressionsCacheBase,
24
-
25
- // @TODO consider passing only an optional integrationsManager to handle impressions
26
- { runtime: { ip, hostname }, version }: Pick<ISettings, 'version' | 'runtime'>,
27
- impressionListener?: SplitIO.IImpressionListener,
28
24
  integrationsManager?: IImpressionsHandler,
29
-
30
25
  // if observer is provided, it implies `shouldAddPreviousTime` flag (i.e., if impressions previous time should be added or not)
31
26
  observer?: IImpressionObserver,
32
27
  // if countsCache is provided, it implies `isOptimized` flag (i.e., if impressions should be deduped or not)
33
28
  countsCache?: IImpressionCountsCacheSync
34
29
  ): IImpressionsTracker {
35
30
 
31
+ const { log, impressionListener, runtime: { ip, hostname }, version } = settings;
32
+
36
33
  return {
37
34
  track(impressions: ImpressionDTO[], attributes?: SplitIO.Attributes) {
35
+ if (settings.userConsent === CONSENT_DECLINED) return;
36
+
38
37
  const impressionsCount = impressions.length;
39
38
 
40
39
  const impressionsToStore: ImpressionDTO[] = []; // Track only the impressions that are going to be stored
@@ -85,7 +84,7 @@ export function impressionsTrackerFactory(
85
84
  // integrationsManager.handleImpression does not throw errors
86
85
  if (integrationsManager) integrationsManager.handleImpression(impressionData);
87
86
 
88
- try { // An exception on the listeners should not break the SDK.
87
+ try { // @ts-ignore. An exception on the listeners should not break the SDK.
89
88
  if (impressionListener) impressionListener.logImpression(impressionData);
90
89
  } catch (err) {
91
90
  log.error(ERROR_IMPRESSIONS_LISTENER, [err]);
package/src/types.ts CHANGED
@@ -54,6 +54,11 @@ type EventConsts = {
54
54
  * @typedef {string} SDKMode
55
55
  */
56
56
  export type SDKMode = 'standalone' | 'consumer' | 'localhost' | 'consumer_partial';
57
+ /**
58
+ * User consent status.
59
+ * @typedef {string} ConsentStatus
60
+ */
61
+ export type ConsentStatus = 'GRANTED' | 'DECLINED' | 'UNKNOWN';
57
62
  /**
58
63
  * Settings interface. This is a representation of the settings the SDK expose, that's why
59
64
  * most of it's props are readonly. Only features should be rewritten when localhost mode is active.
@@ -73,6 +78,7 @@ export interface ISettings {
73
78
  readonly scheduler: {
74
79
  featuresRefreshRate: number,
75
80
  impressionsRefreshRate: number,
81
+ impressionsQueueSize: number,
76
82
  metricsRefreshRate: number,
77
83
  segmentsRefreshRate: number,
78
84
  offlineRefreshRate: number,
@@ -110,6 +116,7 @@ export interface ISettings {
110
116
  },
111
117
  readonly log: ILogger
112
118
  readonly impressionListener?: unknown
119
+ readonly userConsent?: ConsentStatus
113
120
  }
114
121
  /**
115
122
  * Log levels.
@@ -255,6 +262,13 @@ interface INodeBasicSettings extends ISharedSettings {
255
262
  * @default 300
256
263
  */
257
264
  impressionsRefreshRate?: number,
265
+ /**
266
+ * The maximum number of impression items we want to queue. If we queue more values, it will trigger a flush and reset the timer.
267
+ * If you use a 0 here, the queue will have no maximum size.
268
+ * @property {number} impressionsQueueSize
269
+ * @default 30000
270
+ */
271
+ impressionsQueueSize?: number,
258
272
  /**
259
273
  * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
260
274
  * @property {number} metricsRefreshRate
@@ -384,7 +398,7 @@ interface IBasicClient extends IStatusInterface {
384
398
 
385
399
  // Whether the client implements the client-side API, i.e, with bound key, (true), or the server-side API (false).
386
400
  // Exposed for internal purposes only. Not considered part of the public API, and might be renamed eventually.
387
- isBrowserClient: boolean
401
+ isClientSide: boolean
388
402
  }
389
403
  /**
390
404
  * Common definitions between SDK instances for different environments interface.
@@ -769,6 +783,13 @@ export namespace SplitIO {
769
783
  * @default 60
770
784
  */
771
785
  impressionsRefreshRate?: number,
786
+ /**
787
+ * The maximum number of impression items we want to queue. If we queue more values, it will trigger a flush and reset the timer.
788
+ * If you use a 0 here, the queue will have no maximum size.
789
+ * @property {number} impressionsQueueSize
790
+ * @default 30000
791
+ */
792
+ impressionsQueueSize?: number,
772
793
  /**
773
794
  * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
774
795
  * @property {number} metricsRefreshRate
@@ -32,3 +32,8 @@ export const STORAGE_MEMORY: StorageType = 'MEMORY';
32
32
  export const STORAGE_LOCALSTORAGE: StorageType = 'LOCALSTORAGE';
33
33
  export const STORAGE_REDIS: StorageType = 'REDIS';
34
34
  export const STORAGE_PLUGGABLE: StorageType = 'PLUGGABLE';
35
+
36
+ // User consent
37
+ export const CONSENT_GRANTED = 'GRANTED'; // The user has granted consent for tracking events and impressions
38
+ export const CONSENT_DECLINED = 'DECLINED'; // The user has declined consent for tracking events and impressions
39
+ export const CONSENT_UNKNOWN = 'UNKNOWN'; // The user has neither granted nor declined consent for tracking events and impressions
@@ -6,7 +6,7 @@ import { ERROR_NOT_PLAIN_OBJECT } from '../../logger/constants';
6
6
 
7
7
  export function validateAttributes(log: ILogger, maybeAttrs: any, method: string): SplitIO.Attributes | undefined | false {
8
8
  // Attributes are optional
9
- if (isObject(maybeAttrs) || maybeAttrs == undefined) // eslint-disable-line eqeqeq
9
+ if (maybeAttrs == undefined || isObject(maybeAttrs)) // eslint-disable-line eqeqeq
10
10
  return maybeAttrs;
11
11
 
12
12
  log.error(ERROR_NOT_PLAIN_OBJECT, [method, 'attributes']);
@@ -23,5 +23,4 @@ export function validateAttributesDeep(log: ILogger, maybeAttributes: Record<str
23
23
  });
24
24
 
25
25
  return result;
26
-
27
26
  }
@@ -89,7 +89,7 @@ export function get(obj: any, prop: any, val: any): any {
89
89
  /**
90
90
  * Parses an array into a map of different arrays, grouping by the specified prop value.
91
91
  */
92
- export function groupBy<T extends Record<string, any> >(source: T[], prop: string): Record<string, T[]> {
92
+ export function groupBy<T extends Record<string, any>>(source: T[], prop: string): Record<string, T[]> {
93
93
  const map: Record<string, any[]> = {};
94
94
 
95
95
  if (Array.isArray(source) && isString(prop)) {
@@ -151,10 +151,14 @@ export function isNaNNumber(val: any): boolean {
151
151
  }
152
152
 
153
153
  /**
154
- * Validates if a value is an object with the Object prototype (map object).
154
+ * Validates if a value is an object created by the Object constructor (plain object).
155
+ * It checks `constructor.name` to avoid false negatives when validating values on a separate VM context, which has its own global built-ins.
155
156
  */
156
- export function isObject(obj: any): boolean {
157
- return obj !== null && typeof obj === 'object' && obj.constructor === Object;
157
+ export function isObject(obj: any) {
158
+ return obj !== null && typeof obj === 'object' && (
159
+ obj.constructor === Object ||
160
+ (obj.constructor != null && obj.constructor.name === 'Object')
161
+ );
158
162
  }
159
163
 
160
164
  /**
@@ -164,6 +168,13 @@ export function isString(val: any): val is string {
164
168
  return typeof val === 'string' || val instanceof String;
165
169
  }
166
170
 
171
+ /**
172
+ * String sanitizer. Returns the provided value converted to uppercase if it is a string.
173
+ */
174
+ export function stringToUpperCase(val: any) {
175
+ return isString(val) ? val.toUpperCase() : val;
176
+ }
177
+
167
178
  /**
168
179
  * Deep copy version of Object.assign using recursion.
169
180
  * There are some assumptions here. It's for internal use and we don't need verbose errors
@@ -79,4 +79,18 @@ interface IMapConstructor {
79
79
  readonly prototype: IMap<any, any>;
80
80
  }
81
81
 
82
- export const _Map: IMapConstructor = typeof Map !== 'undefined' ? Map : MapPoly;
82
+ /**
83
+ * return the Map constructor to use. If native Map is not available or it doesn't support the required features (e.g., IE11),
84
+ * a ponyfill with minimal features is returned instead.
85
+ *
86
+ * Exported for testing purposes only.
87
+ */
88
+ export function __getMapConstructor(): IMapConstructor {
89
+ // eslint-disable-next-line compat/compat
90
+ if (typeof Array.from === 'function' && typeof Map === 'function' && Map.prototype && Map.prototype.values) {
91
+ return Map;
92
+ }
93
+ return MapPoly;
94
+ }
95
+
96
+ export const _Map = __getMapConstructor();
@@ -0,0 +1,16 @@
1
+ import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
2
+ import { ILogger } from '../../logger/types';
3
+ import { ConsentStatus } from '../../types';
4
+ import { CONSENT_DECLINED, CONSENT_GRANTED, CONSENT_UNKNOWN } from '../constants';
5
+ import { stringToUpperCase } from '../lang';
6
+
7
+ const userConsentValues = [CONSENT_DECLINED, CONSENT_GRANTED, CONSENT_UNKNOWN];
8
+
9
+ export function validateConsent({ userConsent, log }: { userConsent?: any, log: ILogger }): ConsentStatus {
10
+ userConsent = stringToUpperCase(userConsent);
11
+
12
+ if (userConsentValues.indexOf(userConsent) > -1) return userConsent;
13
+
14
+ log.error(ERROR_INVALID_CONFIG_PARAM, ['userConsent', userConsentValues, CONSENT_GRANTED]);
15
+ return CONSENT_GRANTED;
16
+ }
@@ -1,14 +1,14 @@
1
- import { ERROR_INVALID_IMPRESSIONS_MODE } from '../../logger/constants';
1
+ import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
2
2
  import { ILogger } from '../../logger/types';
3
3
  import { SplitIO } from '../../types';
4
4
  import { DEBUG, OPTIMIZED } from '../constants';
5
+ import { stringToUpperCase } from '../lang';
5
6
 
6
- export function validImpressionsMode(log: ILogger, impressionsMode: string): SplitIO.ImpressionsMode {
7
- impressionsMode = impressionsMode.toUpperCase();
8
- if ([DEBUG, OPTIMIZED].indexOf(impressionsMode) === -1) {
9
- log.error(ERROR_INVALID_IMPRESSIONS_MODE, [[DEBUG, OPTIMIZED], OPTIMIZED]);
10
- impressionsMode = OPTIMIZED;
11
- }
7
+ export function validImpressionsMode(log: ILogger, impressionsMode: any): SplitIO.ImpressionsMode {
8
+ impressionsMode = stringToUpperCase(impressionsMode);
12
9
 
13
- return impressionsMode as SplitIO.ImpressionsMode;
10
+ if ([DEBUG, OPTIMIZED].indexOf(impressionsMode) > -1) return impressionsMode;
11
+
12
+ log.error(ERROR_INVALID_CONFIG_PARAM, ['impressionsMode', [DEBUG, OPTIMIZED], OPTIMIZED]);
13
+ return OPTIMIZED;
14
14
  }
@@ -5,6 +5,8 @@ import { STANDALONE_MODE, OPTIMIZED, LOCALHOST_MODE } from '../constants';
5
5
  import { validImpressionsMode } from './impressionsMode';
6
6
  import { ISettingsValidationParams } from './types';
7
7
  import { ISettings } from '../../types';
8
+ import { validateKey } from '../inputValidation/key';
9
+ import { validateTrafficType } from '../inputValidation/trafficType';
8
10
 
9
11
  const base = {
10
12
  // Define which kind of object you want to retrieve from SplitFactory
@@ -38,6 +40,8 @@ const base = {
38
40
  eventsPushRate: 60,
39
41
  // how many events will be queued before flushing
40
42
  eventsQueueSize: 500,
43
+ // how many impressions will be queued before flushing
44
+ impressionsQueueSize: 30000,
41
45
  // backoff base seconds to wait before re attempting to connect to push notifications
42
46
  pushRetryBackoffBase: 1,
43
47
  },
@@ -78,11 +82,6 @@ const base = {
78
82
  localhostMode: undefined
79
83
  },
80
84
 
81
- runtime: {
82
- ip: false,
83
- hostname: false
84
- },
85
-
86
85
  // Logger
87
86
  log: undefined
88
87
  };
@@ -100,7 +99,7 @@ function fromSecondsToMillis(n: number) {
100
99
  */
101
100
  export function settingsValidation(config: unknown, validationParams: ISettingsValidationParams) {
102
101
 
103
- const { defaults, runtime, storage, integrations, logger, localhost } = validationParams;
102
+ const { defaults, runtime, storage, integrations, logger, localhost, consent } = validationParams;
104
103
 
105
104
  // creates a settings object merging base, defaults and config objects.
106
105
  const withDefaults = merge({}, base, defaults, config) as ISettings;
@@ -132,14 +131,30 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
132
131
  // @ts-ignore, modify readonly prop
133
132
  if (storage) withDefaults.storage = storage(withDefaults);
134
133
 
135
- // Although `key` is mandatory according to TS declaration files, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
136
- if (withDefaults.mode === LOCALHOST_MODE && withDefaults.core.key === undefined) {
137
- withDefaults.core.key = 'localhost_key';
134
+ // Validate key and TT (for client-side)
135
+ if (validationParams.acceptKey) {
136
+ const maybeKey = withDefaults.core.key;
137
+ // Although `key` is required in client-side, it can be omitted in LOCALHOST mode. In that case, the value `localhost_key` is used.
138
+ if (withDefaults.mode === LOCALHOST_MODE && maybeKey === undefined) {
139
+ withDefaults.core.key = 'localhost_key';
140
+ } else {
141
+ // Keeping same behaviour than JS SDK: if settings key or TT are invalid,
142
+ // `false` value is used as binded key/TT of the default client, which leads to some issues.
143
+ // @ts-ignore, @TODO handle invalid keys as a non-recoverable error?
144
+ withDefaults.core.key = validateKey(log, maybeKey, 'Client instantiation');
145
+ }
146
+
147
+ if (validationParams.acceptTT) {
148
+ const maybeTT = withDefaults.core.trafficType;
149
+ if (maybeTT !== undefined) { // @ts-ignore
150
+ withDefaults.core.trafficType = validateTrafficType(log, maybeTT, 'Client instantiation');
151
+ }
152
+ }
138
153
  }
139
154
 
140
155
  // Current ip/hostname information
141
156
  // @ts-ignore, modify readonly prop
142
- if (runtime) withDefaults.runtime = runtime(withDefaults);
157
+ withDefaults.runtime = runtime(withDefaults);
143
158
 
144
159
  // ensure a valid list of integrations.
145
160
  // `integrations` returns an array of valid integration items.
@@ -164,5 +179,9 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
164
179
  // ensure a valid impressionsMode
165
180
  withDefaults.sync.impressionsMode = validImpressionsMode(log, withDefaults.sync.impressionsMode);
166
181
 
182
+ // ensure a valid user consent value
183
+ // @ts-ignore, modify readonly prop
184
+ withDefaults.userConsent = consent(withDefaults);
185
+
167
186
  return withDefaults;
168
187
  }
@@ -0,0 +1,9 @@
1
+ import { ISettings } from '../../types';
2
+
3
+ // For client-side SDKs, machine IP and Hostname are not captured and sent to Split backend.
4
+ export function validateRuntime(): ISettings['runtime'] {
5
+ return {
6
+ ip: false,
7
+ hostname: false
8
+ };
9
+ }
@@ -6,18 +6,24 @@ import { ISettings } from '../../types';
6
6
  */
7
7
  export interface ISettingsValidationParams {
8
8
  /**
9
- * Object of values to overwrite default settings.
10
- * Version and startup properties are mandatory, because these values are not part of the base setting.
9
+ * Object of values to overwrite base settings.
10
+ * Version and startup properties are required, because they are not defined in the base settings.
11
11
  */
12
12
  defaults: Partial<ISettings> & { version: string } & { startup: ISettings['startup'] },
13
- /** Function to overwrite runtime values (ip and hostname) which are false by default */
14
- runtime?: (settings: ISettings) => ISettings['runtime'],
15
- /** Storage validator */
13
+ /** If true, validates core.key */
14
+ acceptKey?: boolean,
15
+ /** If true, validates core.trafficType */
16
+ acceptTT?: boolean,
17
+ /** Define runtime values (`settings.runtime`) */
18
+ runtime: (settings: ISettings) => ISettings['runtime'],
19
+ /** Storage validator (`settings.storage`) */
16
20
  storage?: (settings: ISettings) => ISettings['storage'],
17
- /** Integrations validator */
21
+ /** Integrations validator (`settings.integrations`) */
18
22
  integrations?: (settings: ISettings) => ISettings['integrations'],
19
23
  /** Logger validator (`settings.debug`) */
20
24
  logger: (settings: ISettings) => ISettings['log'],
21
25
  /** Localhost mode validator (`settings.sync.localhostMode`) */
22
26
  localhost?: (settings: ISettings) => ISettings['sync']['localhostMode'],
27
+ /** User consent validator (`settings.userConsent`) */
28
+ consent: (settings: ISettings) => ISettings['userConsent'],
23
29
  }
@@ -0,0 +1,2 @@
1
+ import { ISettings } from '../types';
2
+ export declare function isConsentGranted(settings: ISettings): boolean;
@@ -0,0 +1,13 @@
1
+ import { ISdkFactoryContext } from '../sdkFactory/types';
2
+ /**
3
+ * The public user consent API exposed via SplitFactory, used to control if the SDK tracks and sends impressions and events or not.
4
+ */
5
+ export declare function createUserConsentAPI(params: ISdkFactoryContext): {
6
+ setStatus(consent: unknown): boolean;
7
+ getStatus(): import("../types").ConsentStatus | undefined;
8
+ Status: {
9
+ GRANTED: string;
10
+ DECLINED: string;
11
+ UNKNOWN: string;
12
+ };
13
+ };
@@ -5,7 +5,7 @@ import { SplitIO } from '../types';
5
5
  import { ILogger } from '../logger/types';
6
6
  export interface IDependencyMatcherValue {
7
7
  key: SplitIO.SplitKey;
8
- attributes: SplitIO.Attributes;
8
+ attributes?: SplitIO.Attributes;
9
9
  }
10
10
  export interface IMatcherDto {
11
11
  type: number;
@@ -23,6 +23,6 @@ export interface IEvaluation {
23
23
  export declare type IEvaluationResult = IEvaluation & {
24
24
  treatment: string;
25
25
  };
26
- export declare type ISplitEvaluator = (log: ILogger, key: SplitIO.SplitKey, splitName: string, attributes: SplitIO.Attributes, storage: IStorageSync | IStorageAsync) => MaybeThenable<IEvaluation>;
26
+ export declare type ISplitEvaluator = (log: ILogger, key: SplitIO.SplitKey, splitName: string, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync) => MaybeThenable<IEvaluation>;
27
27
  export declare type IEvaluator = (key: SplitIO.SplitKey, seed: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?: ISplitEvaluator) => MaybeThenable<IEvaluation | undefined>;
28
28
  export declare type IMatcher = (...args: any) => MaybeThenable<boolean>;
@@ -4,4 +4,4 @@ import { ILogger } from '../../logger/types';
4
4
  /**
5
5
  * Defines value to be matched (key / attribute).
6
6
  */
7
- export declare function sanitizeValue(log: ILogger, key: string, matcherDto: IMatcherDto, attributes: SplitIO.Attributes): string | number | boolean | (string | number)[] | import("../types").IDependencyMatcherValue | undefined;
7
+ export declare function sanitizeValue(log: ILogger, key: string, matcherDto: IMatcherDto, attributes?: SplitIO.Attributes): string | number | boolean | (string | number)[] | import("../types").IDependencyMatcherValue | undefined;
@@ -4,4 +4,4 @@ import { ILogger } from '../../logger/types';
4
4
  /**
5
5
  * Sanitize matcher value
6
6
  */
7
- export declare function sanitize(log: ILogger, matcherTypeID: number, value: string | number | boolean | Array<string | number> | undefined, dataType: string, attributes: SplitIO.Attributes): string | number | boolean | (string | number)[] | IDependencyMatcherValue | undefined;
7
+ export declare function sanitize(log: ILogger, matcherTypeID: number, value: string | number | boolean | Array<string | number> | undefined, dataType: string, attributes?: SplitIO.Attributes): string | number | boolean | (string | number)[] | IDependencyMatcherValue | undefined;