@splitsoftware/splitio-commons 1.6.2-rc.8 → 1.6.2-rc.9

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 (164) hide show
  1. package/CHANGES.txt +2 -1
  2. package/cjs/consent/sdkUserConsent.js +2 -2
  3. package/cjs/evaluator/index.js +5 -5
  4. package/cjs/listeners/browser.js +1 -2
  5. package/cjs/logger/constants.js +1 -2
  6. package/cjs/sdkClient/client.js +19 -7
  7. package/cjs/sdkClient/sdkClient.js +1 -3
  8. package/cjs/sdkFactory/index.js +5 -23
  9. package/cjs/services/splitApi.js +4 -24
  10. package/cjs/storages/KeyBuilderSS.js +48 -15
  11. package/cjs/storages/inLocalStorage/index.js +1 -5
  12. package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -12
  13. package/cjs/storages/inMemory/InMemoryStorage.js +2 -6
  14. package/cjs/storages/inMemory/InMemoryStorageCS.js +2 -6
  15. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +9 -6
  16. package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
  17. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +100 -0
  18. package/cjs/storages/inRedis/constants.js +1 -4
  19. package/cjs/storages/inRedis/index.js +2 -17
  20. package/cjs/storages/pluggable/TelemetryCachePluggable.js +126 -0
  21. package/cjs/storages/pluggable/index.js +19 -15
  22. package/cjs/sync/submitters/submitterManager.js +0 -3
  23. package/cjs/sync/submitters/telemetrySubmitter.js +7 -5
  24. package/cjs/trackers/impressionsTracker.js +41 -22
  25. package/cjs/utils/constants/index.js +2 -4
  26. package/cjs/utils/lang/maps.js +15 -7
  27. package/cjs/utils/settingsValidation/impressionsMode.js +2 -2
  28. package/cjs/utils/settingsValidation/index.js +0 -3
  29. package/esm/consent/sdkUserConsent.js +2 -2
  30. package/esm/evaluator/index.js +5 -5
  31. package/esm/listeners/browser.js +2 -3
  32. package/esm/logger/constants.js +0 -1
  33. package/esm/sdkClient/client.js +19 -7
  34. package/esm/sdkClient/sdkClient.js +1 -3
  35. package/esm/sdkFactory/index.js +5 -23
  36. package/esm/services/splitApi.js +4 -24
  37. package/esm/storages/KeyBuilderSS.js +44 -14
  38. package/esm/storages/inLocalStorage/index.js +2 -6
  39. package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -12
  40. package/esm/storages/inMemory/InMemoryStorage.js +4 -8
  41. package/esm/storages/inMemory/InMemoryStorageCS.js +3 -7
  42. package/esm/storages/inMemory/TelemetryCacheInMemory.js +8 -6
  43. package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
  44. package/esm/storages/inRedis/TelemetryCacheInRedis.js +100 -0
  45. package/esm/storages/inRedis/constants.js +0 -3
  46. package/esm/storages/inRedis/index.js +3 -18
  47. package/esm/storages/pluggable/TelemetryCachePluggable.js +126 -0
  48. package/esm/storages/pluggable/index.js +19 -15
  49. package/esm/sync/submitters/submitterManager.js +0 -3
  50. package/esm/sync/submitters/telemetrySubmitter.js +8 -6
  51. package/esm/trackers/impressionsTracker.js +41 -22
  52. package/esm/utils/constants/index.js +0 -2
  53. package/esm/utils/lang/maps.js +15 -7
  54. package/esm/utils/settingsValidation/impressionsMode.js +3 -3
  55. package/esm/utils/settingsValidation/index.js +0 -3
  56. package/package.json +2 -1
  57. package/src/consent/sdkUserConsent.ts +2 -2
  58. package/src/evaluator/index.ts +6 -6
  59. package/src/listeners/browser.ts +2 -3
  60. package/src/logger/.DS_Store +0 -0
  61. package/src/logger/constants.ts +0 -1
  62. package/src/sdkClient/client.ts +21 -8
  63. package/src/sdkClient/sdkClient.ts +1 -3
  64. package/src/sdkFactory/index.ts +5 -26
  65. package/src/sdkFactory/types.ts +4 -7
  66. package/src/services/splitApi.ts +4 -26
  67. package/src/services/types.ts +2 -8
  68. package/src/storages/KeyBuilderSS.ts +53 -17
  69. package/src/storages/inLocalStorage/index.ts +2 -5
  70. package/src/storages/inMemory/ImpressionCountsCacheInMemory.ts +1 -16
  71. package/src/storages/inMemory/InMemoryStorage.ts +4 -7
  72. package/src/storages/inMemory/InMemoryStorageCS.ts +3 -7
  73. package/src/storages/inMemory/TelemetryCacheInMemory.ts +9 -7
  74. package/src/storages/inRedis/EventsCacheInRedis.ts +1 -1
  75. package/src/storages/inRedis/TelemetryCacheInRedis.ts +122 -2
  76. package/src/storages/inRedis/constants.ts +0 -3
  77. package/src/storages/inRedis/index.ts +5 -15
  78. package/src/storages/pluggable/TelemetryCachePluggable.ts +147 -2
  79. package/src/storages/pluggable/index.ts +20 -16
  80. package/src/storages/types.ts +13 -31
  81. package/src/sync/submitters/submitterManager.ts +0 -2
  82. package/src/sync/submitters/telemetrySubmitter.ts +14 -9
  83. package/src/sync/submitters/types.ts +40 -26
  84. package/src/trackers/impressionsTracker.ts +48 -27
  85. package/src/trackers/types.ts +0 -28
  86. package/src/types.ts +1 -3
  87. package/src/utils/constants/index.ts +0 -2
  88. package/src/utils/lang/maps.ts +20 -8
  89. package/src/utils/settingsValidation/impressionsMode.ts +3 -3
  90. package/src/utils/settingsValidation/index.ts +0 -4
  91. package/types/logger/constants.d.ts +0 -1
  92. package/types/sdkFactory/types.d.ts +2 -4
  93. package/types/services/types.d.ts +2 -6
  94. package/types/storages/KeyBuilderSS.d.ts +7 -4
  95. package/types/storages/inMemory/ImpressionCountsCacheInMemory.d.ts +1 -5
  96. package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -3
  97. package/types/storages/inRedis/EventsCacheInRedis.d.ts +1 -1
  98. package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +16 -1
  99. package/types/storages/inRedis/constants.d.ts +0 -3
  100. package/types/storages/pluggable/TelemetryCachePluggable.d.ts +17 -1
  101. package/types/storages/types.d.ts +10 -18
  102. package/types/sync/submitters/telemetrySubmitter.d.ts +1 -1
  103. package/types/sync/submitters/types.d.ts +13 -24
  104. package/types/trackers/impressionsTracker.d.ts +6 -4
  105. package/types/trackers/types.d.ts +0 -23
  106. package/types/types.d.ts +1 -3
  107. package/types/utils/constants/index.d.ts +0 -2
  108. package/types/utils/lang/maps.d.ts +6 -2
  109. package/types/utils/settingsValidation/index.d.ts +0 -1
  110. package/cjs/storages/inMemory/uniqueKeysCacheInMemory.js +0 -73
  111. package/cjs/storages/inMemory/uniqueKeysCacheInMemoryCS.js +0 -78
  112. package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +0 -50
  113. package/cjs/storages/inRedis/uniqueKeysCacheInRedis.js +0 -59
  114. package/cjs/sync/submitters/uniqueKeysSubmitter.js +0 -26
  115. package/cjs/trackers/strategy/strategyDebug.js +0 -25
  116. package/cjs/trackers/strategy/strategyNone.js +0 -29
  117. package/cjs/trackers/strategy/strategyOptimized.js +0 -35
  118. package/cjs/trackers/uniqueKeysTracker.js +0 -38
  119. package/esm/storages/inMemory/uniqueKeysCacheInMemory.js +0 -70
  120. package/esm/storages/inMemory/uniqueKeysCacheInMemoryCS.js +0 -75
  121. package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +0 -47
  122. package/esm/storages/inRedis/uniqueKeysCacheInRedis.js +0 -56
  123. package/esm/sync/submitters/uniqueKeysSubmitter.js +0 -22
  124. package/esm/trackers/strategy/strategyDebug.js +0 -21
  125. package/esm/trackers/strategy/strategyNone.js +0 -25
  126. package/esm/trackers/strategy/strategyOptimized.js +0 -31
  127. package/esm/trackers/uniqueKeysTracker.js +0 -34
  128. package/src/storages/inMemory/uniqueKeysCacheInMemory.ts +0 -82
  129. package/src/storages/inMemory/uniqueKeysCacheInMemoryCS.ts +0 -88
  130. package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +0 -52
  131. package/src/storages/inRedis/uniqueKeysCacheInRedis.ts +0 -64
  132. package/src/sync/submitters/uniqueKeysSubmitter.ts +0 -35
  133. package/src/trackers/strategy/strategyDebug.ts +0 -28
  134. package/src/trackers/strategy/strategyNone.ts +0 -34
  135. package/src/trackers/strategy/strategyOptimized.ts +0 -42
  136. package/src/trackers/uniqueKeysTracker.ts +0 -48
  137. package/types/sdkClient/types.d.ts +0 -18
  138. package/types/storages/inMemory/CountsCacheInMemory.d.ts +0 -20
  139. package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +0 -20
  140. package/types/storages/inMemory/uniqueKeysCacheInMemory.d.ts +0 -35
  141. package/types/storages/inMemory/uniqueKeysCacheInMemoryCS.d.ts +0 -37
  142. package/types/storages/inRedis/CountsCacheInRedis.d.ts +0 -9
  143. package/types/storages/inRedis/ImpressionCountsCacheInRedis.d.ts +0 -14
  144. package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +0 -9
  145. package/types/storages/inRedis/uniqueKeysCacheInRedis.d.ts +0 -15
  146. package/types/sync/offline/LocalhostFromFile.d.ts +0 -2
  147. package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +0 -2
  148. package/types/sync/submitters/eventsSyncTask.d.ts +0 -8
  149. package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +0 -5
  150. package/types/sync/submitters/impressionCountsSyncTask.d.ts +0 -13
  151. package/types/sync/submitters/impressionsSyncTask.d.ts +0 -14
  152. package/types/sync/submitters/metricsSyncTask.d.ts +0 -12
  153. package/types/sync/submitters/submitterSyncTask.d.ts +0 -10
  154. package/types/sync/submitters/uniqueKeysSubmitter.d.ts +0 -5
  155. package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +0 -5
  156. package/types/sync/syncTaskComposite.d.ts +0 -5
  157. package/types/trackers/filter/bloomFilter.d.ts +0 -10
  158. package/types/trackers/filter/dictionaryFilter.d.ts +0 -8
  159. package/types/trackers/filter/types.d.ts +0 -5
  160. package/types/trackers/strategy/strategyDebug.d.ts +0 -9
  161. package/types/trackers/strategy/strategyNone.d.ts +0 -10
  162. package/types/trackers/strategy/strategyOptimized.d.ts +0 -11
  163. package/types/trackers/uniqueKeysTracker.d.ts +0 -13
  164. package/types/utils/timeTracker/index.d.ts +0 -70
@@ -1,8 +1,10 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import { thenable } from '../utils/promise/thenable';
3
- import { IImpressionsCacheBase, ITelemetryCacheSync, ITelemetryCacheAsync } from '../storages/types';
4
- import { IImpressionsHandler, IImpressionsTracker, IStrategy } from './types';
3
+ import { truncateTimeFrame } from '../utils/time';
4
+ import { IImpressionCountsCacheSync, IImpressionsCacheBase, ITelemetryCacheSync, ITelemetryCacheAsync } from '../storages/types';
5
+ import { IImpressionsHandler, IImpressionsTracker } from './types';
5
6
  import { SplitIO, ImpressionDTO, ISettings } from '../types';
7
+ import { IImpressionObserver } from './impressionObserver/types';
6
8
  import { IMPRESSIONS_TRACKER_SUCCESS, ERROR_IMPRESSIONS_TRACKER, ERROR_IMPRESSIONS_LISTENER } from '../logger/constants';
7
9
  import { CONSENT_DECLINED, DEDUPED, QUEUED } from '../utils/constants';
8
10
 
@@ -13,14 +15,18 @@ import { CONSENT_DECLINED, DEDUPED, QUEUED } from '../utils/constants';
13
15
  * @param metadata runtime metadata (ip, hostname and version)
14
16
  * @param impressionListener optional impression listener
15
17
  * @param integrationsManager optional integrations manager
16
- * @param strategy strategy for impressions tracking.
18
+ * @param observer optional impression observer. If provided, previous time (pt property) is included in impression instances
19
+ * @param countsCache optional cache to save impressions count. If provided, impressions will be deduped (OPTIMIZED mode)
17
20
  */
18
21
  export function impressionsTrackerFactory(
19
22
  settings: ISettings,
20
23
  impressionsCache: IImpressionsCacheBase,
21
- strategy: IStrategy,
22
24
  integrationsManager?: IImpressionsHandler,
23
- telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync,
25
+ // if observer is provided, it implies `shouldAddPreviousTime` flag (i.e., if impressions previous time should be added or not)
26
+ observer?: IImpressionObserver,
27
+ // if countsCache is provided, it implies `isOptimized` flag (i.e., if impressions should be deduped or not)
28
+ countsCache?: IImpressionCountsCacheSync,
29
+ telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync
24
30
  ): IImpressionsTracker {
25
31
 
26
32
  const { log, impressionListener, runtime: { ip, hostname }, version } = settings;
@@ -30,36 +36,51 @@ export function impressionsTrackerFactory(
30
36
  if (settings.userConsent === CONSENT_DECLINED) return;
31
37
 
32
38
  const impressionsCount = impressions.length;
33
- const { impressionsToStore, impressionsToListener, deduped } = strategy.process(impressions);
34
-
35
- const impressionsToListenerCount = impressionsToListener.length;
36
-
37
- if ( impressionsToStore.length>0 ){
38
- const res = impressionsCache.track(impressionsToStore);
39
39
 
40
- // If we're on an async storage, handle error and log it.
41
- if (thenable(res)) {
42
- res.then(() => {
43
- log.info(IMPRESSIONS_TRACKER_SUCCESS, [impressionsCount]);
44
- }).catch(err => {
45
- log.error(ERROR_IMPRESSIONS_TRACKER, [impressionsCount, err]);
46
- });
47
- } else {
48
- // Record when impressionsCache is sync only (standalone mode)
49
- // @TODO we are not dropping impressions on full queue yet, so DROPPED stats are not recorded
50
- if (telemetryCache) {
51
- (telemetryCache as ITelemetryCacheSync).recordImpressionStats(QUEUED, impressionsToStore.length);
52
- (telemetryCache as ITelemetryCacheSync).recordImpressionStats(DEDUPED, deduped);
53
- }
40
+ const impressionsToStore: ImpressionDTO[] = []; // Track only the impressions that are going to be stored
41
+ // Wraps impressions to store and adds previousTime if it corresponds
42
+ impressions.forEach((impression) => {
43
+ if (observer) {
44
+ // Adds previous time if it is enabled
45
+ impression.pt = observer.testAndSet(impression);
46
+ }
47
+
48
+ const now = Date.now();
49
+ if (countsCache) {
50
+ // Increments impression counter per featureName
51
+ countsCache.track(impression.feature, now, 1);
52
+ }
53
+
54
+ // Checks if the impression should be added in queue to be sent
55
+ if (!countsCache || !impression.pt || impression.pt < truncateTimeFrame(now)) {
56
+ impressionsToStore.push(impression);
57
+ }
58
+ });
59
+
60
+ const res = impressionsCache.track(impressionsToStore);
61
+
62
+ // If we're on an async storage, handle error and log it.
63
+ if (thenable(res)) {
64
+ res.then(() => {
65
+ log.info(IMPRESSIONS_TRACKER_SUCCESS, [impressionsCount]);
66
+ }).catch(err => {
67
+ log.error(ERROR_IMPRESSIONS_TRACKER, [impressionsCount, err]);
68
+ });
69
+ } else {
70
+ // Record when impressionsCache is sync only (standalone mode)
71
+ // @TODO we are not dropping impressions on full queue yet, so DROPPED stats are not recorded
72
+ if (telemetryCache) {
73
+ (telemetryCache as ITelemetryCacheSync).recordImpressionStats(QUEUED, impressionsToStore.length);
74
+ (telemetryCache as ITelemetryCacheSync).recordImpressionStats(DEDUPED, impressions.length - impressionsToStore.length);
54
75
  }
55
76
  }
56
77
 
57
78
  // @TODO next block might be handled by the integration manager. In that case, the metadata object doesn't need to be passed in the constructor
58
79
  if (impressionListener || integrationsManager) {
59
- for (let i = 0; i < impressionsToListenerCount; i++) {
80
+ for (let i = 0; i < impressionsCount; i++) {
60
81
  const impressionData: SplitIO.ImpressionData = {
61
82
  // copy of impression, to avoid unexpected behaviour if modified by integrations or impressionListener
62
- impression: objectAssign({}, impressionsToListener[i]),
83
+ impression: objectAssign({}, impressions[i]),
63
84
  attributes,
64
85
  ip,
65
86
  hostname,
@@ -46,31 +46,3 @@ export interface ITelemetryTracker {
46
46
  */
47
47
  addTag(tag: string): void
48
48
  }
49
-
50
- export interface IFilterAdapter {
51
- add(key: string, featureName: string): boolean;
52
- contains(key: string, featureName: string): boolean;
53
- clear(): void;
54
- refreshRate?: number;
55
- }
56
-
57
- export interface IImpressionSenderAdapter {
58
- recordUniqueKeys(data: Object): void;
59
- recordImpressionCounts(data: Object): void
60
- }
61
-
62
- /** Unique keys tracker */
63
- export interface IUniqueKeysTracker {
64
- stop(): void;
65
- track(key: string, featureName: string): void;
66
- }
67
-
68
- export interface IStrategyResult {
69
- impressionsToStore: ImpressionDTO[],
70
- impressionsToListener: ImpressionDTO[],
71
- deduped: number
72
- }
73
-
74
- export interface IStrategy {
75
- process(impressions: ImpressionDTO[]): IStrategyResult
76
- }
package/src/types.ts CHANGED
@@ -80,8 +80,6 @@ export interface ISettings {
80
80
  featuresRefreshRate: number,
81
81
  impressionsRefreshRate: number,
82
82
  impressionsQueueSize: number,
83
- uniqueKeysRefreshRate: number,
84
- uniqueKeysCacheSize: number,
85
83
  /**
86
84
  * @deprecated
87
85
  */
@@ -720,7 +718,7 @@ export namespace SplitIO {
720
718
  * ImpressionsMode type
721
719
  * @typedef {string} ImpressionsMode
722
720
  */
723
- export type ImpressionsMode = 'OPTIMIZED' | 'DEBUG' | 'NONE'
721
+ export type ImpressionsMode = 'OPTIMIZED' | 'DEBUG'
724
722
  /**
725
723
  * Defines the format of Split data to preload on the factory storage (cache).
726
724
  */
@@ -19,7 +19,6 @@ export const SPLIT_EVENT = 'EVENT';
19
19
  // Impression collection modes
20
20
  export const DEBUG = 'DEBUG';
21
21
  export const OPTIMIZED = 'OPTIMIZED';
22
- export const NONE = 'NONE';
23
22
 
24
23
  // SDK Modes
25
24
  export const LOCALHOST_MODE: SDKMode = 'localhost';
@@ -50,7 +49,6 @@ export const CONSUMER_PARTIAL_ENUM = 2;
50
49
 
51
50
  export const OPTIMIZED_ENUM = 0;
52
51
  export const DEBUG_ENUM = 1;
53
- export const NONE_ENUM = 2;
54
52
 
55
53
  export const SPLITS = 'sp';
56
54
  export const IMPRESSIONS = 'im';
@@ -24,10 +24,12 @@ THE SOFTWARE.
24
24
  **/
25
25
 
26
26
  export interface IMap<K, V> {
27
- set(key: K, value: V): this;
28
27
  clear(): void;
29
28
  delete(key: K): boolean;
29
+ forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
30
30
  get(key: K): V | undefined;
31
+ has(key: K): boolean;
32
+ set(key: K, value: V): this;
31
33
  readonly size: number;
32
34
  }
33
35
 
@@ -46,13 +48,6 @@ export class MapPoly<K, V> implements IMap<K, V>{
46
48
  this.__mapValuesData__.length = 0;
47
49
  }
48
50
 
49
- set(key: K, value: V) {
50
- let index = this.__mapKeysData__.indexOf(key);
51
- if (index === -1) index = this.__mapKeysData__.push(key) - 1;
52
- this.__mapValuesData__[index] = value;
53
- return this;
54
- }
55
-
56
51
  delete(key: K) {
57
52
  const index = this.__mapKeysData__.indexOf(key);
58
53
  if (index === -1) return false;
@@ -61,12 +56,29 @@ export class MapPoly<K, V> implements IMap<K, V>{
61
56
  return true;
62
57
  }
63
58
 
59
+ forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any) {
60
+ for (let i = 0; i < this.__mapKeysData__.length; i++) {
61
+ callbackfn.call(thisArg, this.__mapValuesData__[i], this.__mapKeysData__[i], this as any);
62
+ }
63
+ }
64
+
64
65
  get(key: K) {
65
66
  const index = this.__mapKeysData__.indexOf(key);
66
67
  if (index === -1) return;
67
68
  return this.__mapValuesData__[index];
68
69
  }
69
70
 
71
+ has(key: K): boolean {
72
+ return this.__mapKeysData__.indexOf(key) !== -1;
73
+ }
74
+
75
+ set(key: K, value: V) {
76
+ let index = this.__mapKeysData__.indexOf(key);
77
+ if (index === -1) index = this.__mapKeysData__.push(key) - 1;
78
+ this.__mapValuesData__[index] = value;
79
+ return this;
80
+ }
81
+
70
82
  get size() {
71
83
  return this.__mapKeysData__.length;
72
84
  }
@@ -1,14 +1,14 @@
1
1
  import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
2
2
  import { ILogger } from '../../logger/types';
3
3
  import { SplitIO } from '../../types';
4
- import { DEBUG, OPTIMIZED, NONE } from '../constants';
4
+ import { DEBUG, OPTIMIZED } from '../constants';
5
5
  import { stringToUpperCase } from '../lang';
6
6
 
7
7
  export function validImpressionsMode(log: ILogger, impressionsMode: any): SplitIO.ImpressionsMode {
8
8
  impressionsMode = stringToUpperCase(impressionsMode);
9
9
 
10
- if ([DEBUG, OPTIMIZED, NONE].indexOf(impressionsMode) > -1) return impressionsMode;
10
+ if ([DEBUG, OPTIMIZED].indexOf(impressionsMode) > -1) return impressionsMode;
11
11
 
12
- log.error(ERROR_INVALID_CONFIG_PARAM, ['impressionsMode', [DEBUG, OPTIMIZED, NONE], OPTIMIZED]);
12
+ log.error(ERROR_INVALID_CONFIG_PARAM, ['impressionsMode', [DEBUG, OPTIMIZED], OPTIMIZED]);
13
13
  return OPTIMIZED;
14
14
  }
@@ -36,8 +36,6 @@ export const base = {
36
36
  telemetryRefreshRate: 3600,
37
37
  // publish evaluations each 300 sec (default value for OPTIMIZED impressions mode)
38
38
  impressionsRefreshRate: 300,
39
- // publish unique Keys each 900 sec (15 min)
40
- uniqueKeysRefreshRate: 900,
41
39
  // fetch offline changes each 15 sec
42
40
  offlineRefreshRate: 15,
43
41
  // publish events every 60 seconds after the first flush
@@ -132,13 +130,11 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
132
130
  scheduler.segmentsRefreshRate = fromSecondsToMillis(scheduler.segmentsRefreshRate);
133
131
  scheduler.offlineRefreshRate = fromSecondsToMillis(scheduler.offlineRefreshRate);
134
132
  scheduler.eventsPushRate = fromSecondsToMillis(scheduler.eventsPushRate);
135
- scheduler.uniqueKeysRefreshRate = fromSecondsToMillis(scheduler.uniqueKeysRefreshRate);
136
133
  scheduler.telemetryRefreshRate = fromSecondsToMillis(validateMinValue('telemetryRefreshRate', scheduler.telemetryRefreshRate, 60));
137
134
 
138
135
  // Default impressionsRefreshRate for DEBUG mode is 60 secs
139
136
  if (get(config, 'scheduler.impressionsRefreshRate') === undefined && withDefaults.sync.impressionsMode === DEBUG) scheduler.impressionsRefreshRate = 60;
140
137
  scheduler.impressionsRefreshRate = fromSecondsToMillis(scheduler.impressionsRefreshRate);
141
-
142
138
 
143
139
  // Log deprecation for old telemetry param
144
140
  if (scheduler.metricsRefreshRate) log.warn('`metricsRefreshRate` will be deprecated soon. For configuring telemetry rates, update `telemetryRefreshRate` value in configs');
@@ -138,5 +138,4 @@ export declare const LOG_PREFIX_SYNC_POLLING: string;
138
138
  export declare const LOG_PREFIX_SYNC_SUBMITTERS: string;
139
139
  export declare const LOG_PREFIX_IMPRESSIONS_TRACKER = "impressions-tracker: ";
140
140
  export declare const LOG_PREFIX_EVENTS_TRACKER = "events-tracker: ";
141
- export declare const LOG_PREFIX_UNIQUE_KEYS_TRACKER = "unique-keys-tracker: ";
142
141
  export declare const LOG_PREFIX_CLEANUP = "cleanup: ";
@@ -6,7 +6,7 @@ import { IFetch, ISplitApi, IEventSourceConstructor } from '../services/types';
6
6
  import { IStorageAsync, IStorageSync, ISplitsCacheSync, ISplitsCacheAsync, IStorageFactoryParams } from '../storages/types';
7
7
  import { ISyncManager } from '../sync/types';
8
8
  import { IImpressionObserver } from '../trackers/impressionObserver/types';
9
- import { IImpressionsTracker, IEventTracker, ITelemetryTracker, IFilterAdapter, IUniqueKeysTracker } from '../trackers/types';
9
+ import { IImpressionsTracker, IEventTracker, ITelemetryTracker } from '../trackers/types';
10
10
  import { SplitIO, ISettings, IEventEmitter } from '../types';
11
11
  /**
12
12
  * Environment related dependencies.
@@ -42,7 +42,6 @@ export interface ISdkFactoryContext {
42
42
  eventTracker: IEventTracker;
43
43
  telemetryTracker: ITelemetryTracker;
44
44
  storage: IStorageSync | IStorageAsync;
45
- uniqueKeysTracker?: IUniqueKeysTracker;
46
45
  signalListener?: ISignalListener;
47
46
  splitApi?: ISplitApi;
48
47
  syncManager?: ISyncManager;
@@ -71,12 +70,11 @@ export interface ISdkFactoryParams {
71
70
  (): SplitIO.ICsClient;
72
71
  (key: SplitIO.SplitKey, trafficType?: string | undefined): SplitIO.ICsClient;
73
72
  } | (() => SplitIO.IClient) | (() => SplitIO.IAsyncClient));
74
- impressionsObserverFactory: () => IImpressionObserver;
75
- filterAdapterFactory?: () => IFilterAdapter;
76
73
  SignalListener?: new (syncManager: ISyncManager | undefined, // Used by NodeSignalListener to flush data, and by BrowserSignalListener to close streaming connection.
77
74
  settings: ISettings, // Used by BrowserSignalListener
78
75
  storage: IStorageSync | IStorageAsync, // Used by BrowserSignalListener
79
76
  serviceApi: ISplitApi | undefined) => ISignalListener;
80
77
  integrationsManagerFactory?: (params: IIntegrationFactoryParams) => IIntegrationManager | undefined;
78
+ impressionsObserverFactory?: () => IImpressionObserver;
81
79
  extraProps?: (params: ISdkFactoryContext) => object;
82
80
  }
@@ -20,12 +20,10 @@ export declare type IFetchSplitChanges = (since: number, noCache?: boolean, till
20
20
  export declare type IFetchSegmentChanges = (since: number, segmentName: string, noCache?: boolean, till?: number) => Promise<IResponse>;
21
21
  export declare type IFetchMySegments = (userMatchingKey: string, noCache?: boolean) => Promise<IResponse>;
22
22
  export declare type IPostEventsBulk = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
23
- export declare type IPostUniqueKeysBulkCs = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
24
- export declare type IPostUniqueKeysBulkSs = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
25
23
  export declare type IPostTestImpressionsBulk = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
26
24
  export declare type IPostTestImpressionsCount = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
27
- export declare type IPostMetricsConfig = (body: string) => Promise<IResponse>;
28
- export declare type IPostMetricsUsage = (body: string) => Promise<IResponse>;
25
+ export declare type IPostMetricsConfig = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
26
+ export declare type IPostMetricsUsage = (body: string, headers?: Record<string, string>) => Promise<IResponse>;
29
27
  export interface ISplitApi {
30
28
  getSdkAPIHealthCheck: IHealthCheckAPI;
31
29
  getEventsAPIHealthCheck: IHealthCheckAPI;
@@ -34,8 +32,6 @@ export interface ISplitApi {
34
32
  fetchSegmentChanges: IFetchSegmentChanges;
35
33
  fetchMySegments: IFetchMySegments;
36
34
  postEventsBulk: IPostEventsBulk;
37
- postUniqueKeysBulkCs: IPostUniqueKeysBulkCs;
38
- postUniqueKeysBulkSs: IPostUniqueKeysBulkSs;
39
35
  postTestImpressionsBulk: IPostTestImpressionsBulk;
40
36
  postTestImpressionsCount: IPostTestImpressionsCount;
41
37
  postMetricsConfig: IPostMetricsConfig;
@@ -2,16 +2,19 @@ import { KeyBuilder } from './KeyBuilder';
2
2
  import { IMetadata } from '../dtos/types';
3
3
  import { Method } from '../sync/submitters/types';
4
4
  export declare class KeyBuilderSS extends KeyBuilder {
5
- protected readonly metadata: IMetadata;
5
+ latencyPrefix: string;
6
+ exceptionPrefix: string;
7
+ initPrefix: string;
8
+ private versionablePrefix;
6
9
  constructor(prefix: string, metadata: IMetadata);
7
10
  buildRegisteredSegmentsKey(): string;
8
11
  buildImpressionsKey(): string;
9
- buildImpressionsCountKey(): string;
10
- buildUniqueKeysKey(): string;
11
12
  buildEventsKey(): string;
12
13
  searchPatternForSplitKeys(): string;
13
14
  buildLatencyKey(method: Method, bucket: number): string;
14
15
  buildExceptionKey(method: Method): string;
15
16
  buildInitKey(): string;
16
- private buildVersionablePrefix;
17
17
  }
18
+ export declare function parseMetadata(field: string): [metadata: string] | string;
19
+ export declare function parseExceptionField(field: string): [metadata: string, method: Method] | string;
20
+ export declare function parseLatencyField(field: string): [metadata: string, method: Method, bucket: number] | string;
@@ -1,10 +1,6 @@
1
1
  import { IImpressionCountsCacheSync } from '../types';
2
2
  export declare class ImpressionCountsCacheInMemory implements IImpressionCountsCacheSync {
3
- protected cache: Record<string, number>;
4
- private readonly maxStorage;
5
- protected onFullQueue?: () => void;
6
- private cacheSize;
7
- constructor(impressionCountsCacheSize?: number);
3
+ private cache;
8
4
  /**
9
5
  * Builds key to be stored in the cache with the featureName and the timeFrame truncated.
10
6
  */
@@ -1,9 +1,12 @@
1
1
  import { ImpressionDataType, EventDataType, LastSync, HttpErrors, HttpLatencies, StreamingEvent, Method, OperationType, MethodExceptions, MethodLatencies } from '../../sync/submitters/types';
2
- import { ITelemetryCacheSync } from '../types';
2
+ import { IStorageFactoryParams, ITelemetryCacheSync } from '../types';
3
+ export declare const MAX_LATENCY_BUCKET_COUNT = 23;
4
+ export declare function newBuckets(): any[];
3
5
  /**
4
- * Used on client-side. 0.1% of instances will track telemetry
6
+ * Record telemetry if mode is not localhost.
7
+ * All factory instances track telemetry on server-side, and 0.1% on client-side.
5
8
  */
6
- export declare function shouldRecordTelemetry(): boolean;
9
+ export declare function shouldRecordTelemetry(params: IStorageFactoryParams): boolean;
7
10
  export declare class TelemetryCacheInMemory implements ITelemetryCacheSync {
8
11
  private timeUntilReady?;
9
12
  getTimeUntilReady(): number | undefined;
@@ -23,7 +23,7 @@ export declare class EventsCacheInRedis implements IEventsCacheAsync {
23
23
  drop(count?: number): Promise<any>;
24
24
  /**
25
25
  * Pop the given number of events from the storage.
26
- * The returned promise rejects if the wrapper operation fails.
26
+ * The returned promise rejects if the redis operation fails.
27
27
  *
28
28
  * NOTE: this method doesn't take into account MAX_EVENT_SIZE or MAX_QUEUE_BYTE_SIZE limits.
29
29
  * It is the submitter responsability to handle that.
@@ -1,5 +1,5 @@
1
1
  import { ILogger } from '../../logger/types';
2
- import { Method } from '../../sync/submitters/types';
2
+ import { Method, MultiConfigs, MultiMethodExceptions, MultiMethodLatencies } from '../../sync/submitters/types';
3
3
  import { KeyBuilderSS } from '../KeyBuilderSS';
4
4
  import { ITelemetryCacheAsync } from '../types';
5
5
  import { Redis } from 'ioredis';
@@ -17,4 +17,19 @@ export declare class TelemetryCacheInRedis implements ITelemetryCacheAsync {
17
17
  recordLatency(method: Method, latencyMs: number): Promise<number | void>;
18
18
  recordException(method: Method): Promise<number | void>;
19
19
  recordConfig(): Promise<number | void>;
20
+ /**
21
+ * Pop telemetry latencies.
22
+ * The returned promise rejects if redis operations fail.
23
+ */
24
+ popLatencies(): Promise<MultiMethodLatencies>;
25
+ /**
26
+ * Pop telemetry exceptions.
27
+ * The returned promise rejects if redis operations fail.
28
+ */
29
+ popExceptions(): Promise<MultiMethodExceptions>;
30
+ /**
31
+ * Pop telemetry configs.
32
+ * The returned promise rejects if redis operations fail.
33
+ */
34
+ popConfigs(): Promise<MultiConfigs>;
20
35
  }
@@ -1,4 +1 @@
1
1
  export declare const LOG_PREFIX = "storage:redis: ";
2
- export declare const DEFAULT_CACHE_SIZE = 30000;
3
- export declare const REFRESH_RATE = 300000;
4
- export declare const TTL_REFRESH = 3600;
@@ -1,5 +1,5 @@
1
1
  import { ILogger } from '../../logger/types';
2
- import { Method } from '../../sync/submitters/types';
2
+ import { Method, MultiConfigs, MultiMethodExceptions, MultiMethodLatencies } from '../../sync/submitters/types';
3
3
  import { KeyBuilderSS } from '../KeyBuilderSS';
4
4
  import { IPluggableStorageWrapper, ITelemetryCacheAsync } from '../types';
5
5
  export declare class TelemetryCachePluggable implements ITelemetryCacheAsync {
@@ -15,4 +15,20 @@ export declare class TelemetryCachePluggable implements ITelemetryCacheAsync {
15
15
  constructor(log: ILogger, keys: KeyBuilderSS, wrapper: IPluggableStorageWrapper);
16
16
  recordLatency(method: Method, latencyMs: number): Promise<number | void>;
17
17
  recordException(method: Method): Promise<number | void>;
18
+ recordConfig(): Promise<boolean | void>;
19
+ /**
20
+ * Pop telemetry latencies.
21
+ * The returned promise rejects if wrapper operations fail.
22
+ */
23
+ popLatencies(): Promise<MultiMethodLatencies>;
24
+ /**
25
+ * Pop telemetry exceptions.
26
+ * The returned promise rejects if wrapper operations fail.
27
+ */
28
+ popExceptions(): Promise<MultiMethodExceptions>;
29
+ /**
30
+ * Pop telemetry configs.
31
+ * The returned promise rejects if wrapper operations fail.
32
+ */
33
+ popConfigs(): Promise<MultiConfigs>;
18
34
  }
@@ -1,6 +1,6 @@
1
1
  import { MaybeThenable, IMetadata, ISplitFiltersValidation, ISplit } from '../dtos/types';
2
2
  import { ILogger } from '../logger/types';
3
- import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs } from '../sync/submitters/types';
3
+ import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent } from '../sync/submitters/types';
4
4
  import { SplitIO, ImpressionDTO, SDKMode } from '../types';
5
5
  /**
6
6
  * Interface of a pluggable storage wrapper.
@@ -297,13 +297,6 @@ export interface IImpressionCountsCacheSync extends IRecorderCacheProducerSync<R
297
297
  isEmpty(): boolean;
298
298
  pop(toMerge?: Record<string, number>): Record<string, number>;
299
299
  }
300
- export interface IUniqueKeysCacheBase {
301
- track(key: string, value: string): void;
302
- isEmpty(): boolean;
303
- pop(): UniqueKeysPayloadSs | UniqueKeysPayloadCs;
304
- setOnFullQueueCb(cb: () => void): void;
305
- clear(): void;
306
- }
307
300
  /**
308
301
  * Telemetry storage interface for standalone and partial consumer modes.
309
302
  * Methods are sync because data is stored in memory.
@@ -361,43 +354,42 @@ export interface ITelemetryCacheSync extends ITelemetryStorageConsumerSync, ITel
361
354
  * Methods are async because data is stored in Redis or a pluggable storage.
362
355
  */
363
356
  export interface ITelemetryEvaluationConsumerAsync {
364
- popExceptions(): Promise<MethodExceptions>;
365
- popLatencies(): Promise<MethodLatencies>;
357
+ popLatencies(): Promise<MultiMethodLatencies>;
358
+ popExceptions(): Promise<MultiMethodExceptions>;
359
+ popConfigs(): Promise<MultiConfigs>;
366
360
  }
367
361
  export interface ITelemetryEvaluationProducerAsync {
368
362
  recordLatency(method: Method, latencyMs: number): Promise<any>;
369
363
  recordException(method: Method): Promise<any>;
364
+ recordConfig(): Promise<any>;
370
365
  }
371
- export interface ITelemetryCacheAsync extends ITelemetryEvaluationProducerAsync {
366
+ export interface ITelemetryCacheAsync extends ITelemetryEvaluationProducerAsync, ITelemetryEvaluationConsumerAsync {
372
367
  }
373
368
  /**
374
369
  * Storages
375
370
  */
376
- export interface IStorageBase<TSplitsCache extends ISplitsCacheBase, TSegmentsCache extends ISegmentsCacheBase, TImpressionsCache extends IImpressionsCacheBase, TImpressionsCountCache extends IImpressionCountsCacheSync, TEventsCache extends IEventsCacheBase, TTelemetryCache extends ITelemetryCacheSync | ITelemetryCacheAsync, TUniqueKeysCache extends IUniqueKeysCacheBase> {
371
+ export interface IStorageBase<TSplitsCache extends ISplitsCacheBase, TSegmentsCache extends ISegmentsCacheBase, TImpressionsCache extends IImpressionsCacheBase, TEventsCache extends IEventsCacheBase, TTelemetryCache extends ITelemetryCacheSync | ITelemetryCacheAsync> {
377
372
  splits: TSplitsCache;
378
373
  segments: TSegmentsCache;
379
374
  impressions: TImpressionsCache;
380
- impressionCounts?: TImpressionsCountCache;
375
+ impressionCounts?: IImpressionCountsCacheSync;
381
376
  events: TEventsCache;
382
377
  telemetry?: TTelemetryCache;
383
- uniqueKeys?: TUniqueKeysCache;
384
378
  destroy(): void | Promise<void>;
385
379
  shared?: (matchingKey: string, onReadyCb: (error?: any) => void) => this;
386
380
  }
387
- export interface IStorageSync extends IStorageBase<ISplitsCacheSync, ISegmentsCacheSync, IImpressionsCacheSync, IImpressionCountsCacheSync, IEventsCacheSync, ITelemetryCacheSync, IUniqueKeysCacheBase> {
381
+ export interface IStorageSync extends IStorageBase<ISplitsCacheSync, ISegmentsCacheSync, IImpressionsCacheSync, IEventsCacheSync, ITelemetryCacheSync> {
388
382
  }
389
- export interface IStorageAsync extends IStorageBase<ISplitsCacheAsync, ISegmentsCacheAsync, IImpressionsCacheAsync | IImpressionsCacheSync, IImpressionCountsCacheSync, IEventsCacheAsync | IEventsCacheSync, ITelemetryCacheAsync, IUniqueKeysCacheBase> {
383
+ export interface IStorageAsync extends IStorageBase<ISplitsCacheAsync, ISegmentsCacheAsync, IImpressionsCacheAsync | IImpressionsCacheSync, IEventsCacheAsync | IEventsCacheSync, ITelemetryCacheAsync | ITelemetryCacheSync> {
390
384
  }
391
385
  /** StorageFactory */
392
386
  export declare type DataLoader = (storage: IStorageSync, matchingKey: string) => void;
393
387
  export interface IStorageFactoryParams {
394
388
  log: ILogger;
395
389
  impressionsQueueSize?: number;
396
- uniqueKeysCacheSize?: number;
397
390
  eventsQueueSize?: number;
398
391
  optimize?: boolean;
399
392
  mode: SDKMode;
400
- impressionsMode?: string;
401
393
  matchingKey?: string;
402
394
  splitFiltersValidation?: ISplitFiltersValidation;
403
395
  onReadyCb: (error?: any) => void;
@@ -5,7 +5,7 @@ import { ISdkFactoryContextSync } from '../../sdkFactory/types';
5
5
  /**
6
6
  * Converts data from telemetry cache into /metrics/usage request payload.
7
7
  */
8
- export declare function telemetryCacheStatsAdapter(telemetry: ITelemetryCacheSync, splits: ISplitsCacheSync, segments: ISegmentsCacheSync): {
8
+ export declare function telemetryCacheStatsAdapter(telemetry: ITelemetryCacheSync, splits?: ISplitsCacheSync, segments?: ISegmentsCacheSync): {
9
9
  isEmpty(): boolean;
10
10
  clear(): void;
11
11
  pop(): TelemetryUsageStatsPayload;
@@ -1,5 +1,6 @@
1
1
  import { IMetadata } from '../../dtos/types';
2
2
  import { SplitIO } from '../../types';
3
+ import { IMap } from '../../utils/lang/maps';
3
4
  import { ISyncTask } from '../types';
4
5
  export declare type ImpressionsPayload = {
5
6
  /** Split name */
@@ -32,22 +33,6 @@ export declare type ImpressionCountsPayload = {
32
33
  rc: number;
33
34
  }[];
34
35
  };
35
- export declare type UniqueKeysPayloadSs = {
36
- keys: {
37
- /** Split name */
38
- f: string;
39
- /** keyNames */
40
- ks: string[];
41
- }[];
42
- };
43
- export declare type UniqueKeysPayloadCs = {
44
- keys: {
45
- /** keyNames */
46
- k: string;
47
- /** Split name */
48
- fs: string[];
49
- }[];
50
- };
51
36
  export declare type StoredImpressionWithMetadata = {
52
37
  /** Metadata */
53
38
  m: IMetadata;
@@ -75,6 +60,9 @@ export declare type StoredEventWithMetadata = {
75
60
  /** Stored event */
76
61
  e: SplitIO.EventData;
77
62
  };
63
+ export declare type MultiMethodLatencies = IMap<string, MethodLatencies>;
64
+ export declare type MultiMethodExceptions = IMap<string, MethodExceptions>;
65
+ export declare type MultiConfigs = IMap<string, TelemetryConfigStats>;
78
66
  /**
79
67
  * Telemetry usage stats
80
68
  */
@@ -119,10 +107,12 @@ export declare type StreamingEvent = {
119
107
  d?: number;
120
108
  t: number;
121
109
  };
122
- export declare type TelemetryUsageStatsPayload = {
110
+ export declare type TelemetryUsageStats = {
111
+ mL?: MethodLatencies;
112
+ mE?: MethodExceptions;
113
+ };
114
+ export declare type TelemetryUsageStatsPayload = TelemetryUsageStats & {
123
115
  lS: LastSync;
124
- mL: MethodLatencies;
125
- mE: MethodExceptions;
126
116
  hE: HttpErrors;
127
117
  hL: HttpLatencies;
128
118
  tR: number;
@@ -130,9 +120,9 @@ export declare type TelemetryUsageStatsPayload = {
130
120
  iQ: number;
131
121
  iDe: number;
132
122
  iDr: number;
133
- spC: number;
134
- seC: number;
135
- skC: number;
123
+ spC?: number;
124
+ seC?: number;
125
+ skC?: number;
136
126
  sL?: number;
137
127
  eQ: number;
138
128
  eD: number;
@@ -148,8 +138,7 @@ export declare type CONSUMER_PARTIAL_ENUM = 2;
148
138
  export declare type OperationMode = STANDALONE_ENUM | CONSUMER_ENUM | CONSUMER_PARTIAL_ENUM;
149
139
  export declare type OPTIMIZED_ENUM = 0;
150
140
  export declare type DEBUG_ENUM = 1;
151
- export declare type NONE_ENUM = 2;
152
- export declare type ImpressionsMode = OPTIMIZED_ENUM | DEBUG_ENUM | NONE_ENUM;
141
+ export declare type ImpressionsMode = OPTIMIZED_ENUM | DEBUG_ENUM;
153
142
  export declare type RefreshRates = {
154
143
  sp: number;
155
144
  se?: number;