@splitsoftware/splitio-commons 1.9.1-rc.0 → 1.9.2-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 (144) hide show
  1. package/CHANGES.txt +5 -2
  2. package/cjs/evaluator/index.js +18 -1
  3. package/cjs/integrations/ga/GaToSplit.js +1 -1
  4. package/cjs/listeners/browser.js +3 -13
  5. package/cjs/logger/constants.js +7 -2
  6. package/cjs/logger/messages/error.js +2 -0
  7. package/cjs/logger/messages/warn.js +3 -1
  8. package/cjs/myLogger.js +34 -0
  9. package/cjs/sdkClient/client.js +33 -0
  10. package/cjs/sdkClient/clientAttributesDecoration.js +20 -0
  11. package/cjs/sdkClient/clientCS.js +5 -4
  12. package/cjs/sdkClient/clientInputValidation.js +52 -3
  13. package/cjs/sdkManager/index.js +2 -1
  14. package/cjs/services/splitApi.js +7 -1
  15. package/cjs/storages/KeyBuilder.js +3 -0
  16. package/cjs/storages/KeyBuilderSS.js +4 -0
  17. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +63 -27
  18. package/cjs/storages/inLocalStorage/index.js +2 -2
  19. package/cjs/storages/inMemory/InMemoryStorage.js +2 -2
  20. package/cjs/storages/inMemory/InMemoryStorageCS.js +3 -3
  21. package/cjs/storages/inMemory/SplitsCacheInMemory.js +47 -2
  22. package/cjs/storages/inRedis/SplitsCacheInRedis.js +11 -0
  23. package/cjs/storages/pluggable/SplitsCachePluggable.js +11 -0
  24. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  25. package/cjs/sync/polling/updaters/splitChangesUpdater.js +24 -4
  26. package/cjs/sync/streaming/parseUtils.js +1 -0
  27. package/cjs/sync/submitters/telemetrySubmitter.js +15 -1
  28. package/cjs/utils/constants/index.js +6 -2
  29. package/cjs/utils/lang/sets.js +9 -1
  30. package/cjs/utils/settingsValidation/splitFilters.js +77 -2
  31. package/esm/evaluator/index.js +16 -0
  32. package/esm/integrations/ga/GaToSplit.js +1 -1
  33. package/esm/listeners/browser.js +3 -13
  34. package/esm/logger/constants.js +5 -0
  35. package/esm/logger/messages/error.js +2 -0
  36. package/esm/logger/messages/warn.js +3 -1
  37. package/esm/myLogger.js +31 -0
  38. package/esm/sdkClient/client.js +35 -2
  39. package/esm/sdkClient/clientAttributesDecoration.js +20 -0
  40. package/esm/sdkClient/clientCS.js +5 -4
  41. package/esm/sdkClient/clientInputValidation.js +52 -3
  42. package/esm/sdkManager/index.js +2 -1
  43. package/esm/services/splitApi.js +7 -1
  44. package/esm/storages/KeyBuilder.js +3 -0
  45. package/esm/storages/KeyBuilderSS.js +4 -0
  46. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +63 -27
  47. package/esm/storages/inLocalStorage/index.js +2 -2
  48. package/esm/storages/inMemory/InMemoryStorage.js +2 -2
  49. package/esm/storages/inMemory/InMemoryStorageCS.js +3 -3
  50. package/esm/storages/inMemory/SplitsCacheInMemory.js +47 -2
  51. package/esm/storages/inRedis/SplitsCacheInRedis.js +11 -0
  52. package/esm/storages/pluggable/SplitsCachePluggable.js +11 -0
  53. package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  54. package/esm/sync/polling/updaters/splitChangesUpdater.js +24 -4
  55. package/esm/sync/streaming/parseUtils.js +1 -0
  56. package/esm/sync/submitters/telemetrySubmitter.js +15 -1
  57. package/esm/utils/constants/index.js +4 -0
  58. package/esm/utils/lang/sets.js +7 -0
  59. package/esm/utils/settingsValidation/splitFilters.js +76 -2
  60. package/package.json +6 -6
  61. package/src/dtos/types.ts +3 -2
  62. package/src/evaluator/index.ts +24 -0
  63. package/src/integrations/ga/GaToSplit.ts +1 -1
  64. package/src/listeners/browser.ts +3 -13
  65. package/src/logger/constants.ts +5 -0
  66. package/src/logger/messages/error.ts +2 -0
  67. package/src/logger/messages/warn.ts +3 -1
  68. package/src/myLogger.ts +36 -0
  69. package/src/sdkClient/client.ts +42 -2
  70. package/src/sdkClient/clientAttributesDecoration.ts +24 -0
  71. package/src/sdkClient/clientCS.ts +5 -4
  72. package/src/sdkClient/clientInputValidation.ts +56 -4
  73. package/src/sdkManager/index.ts +2 -1
  74. package/src/services/splitApi.ts +6 -1
  75. package/src/storages/AbstractSplitsCacheAsync.ts +2 -0
  76. package/src/storages/AbstractSplitsCacheSync.ts +3 -0
  77. package/src/storages/KeyBuilder.ts +4 -0
  78. package/src/storages/KeyBuilderSS.ts +4 -0
  79. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +74 -28
  80. package/src/storages/inLocalStorage/index.ts +2 -2
  81. package/src/storages/inMemory/InMemoryStorage.ts +2 -2
  82. package/src/storages/inMemory/InMemoryStorageCS.ts +3 -3
  83. package/src/storages/inMemory/SplitsCacheInMemory.ts +50 -1
  84. package/src/storages/inMemory/TelemetryCacheInMemory.ts +1 -1
  85. package/src/storages/inRedis/RedisAdapter.ts +1 -1
  86. package/src/storages/inRedis/SplitsCacheInRedis.ts +12 -0
  87. package/src/storages/pluggable/SplitsCachePluggable.ts +12 -0
  88. package/src/storages/types.ts +7 -3
  89. package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -0
  90. package/src/sync/polling/updaters/splitChangesUpdater.ts +27 -4
  91. package/src/sync/streaming/parseUtils.ts +1 -0
  92. package/src/sync/submitters/telemetrySubmitter.ts +19 -2
  93. package/src/sync/submitters/types.ts +7 -1
  94. package/src/types.ts +118 -1
  95. package/src/utils/constants/index.ts +4 -0
  96. package/src/utils/lang/sets.ts +8 -0
  97. package/src/utils/redis/RedisMock.ts +1 -1
  98. package/src/utils/settingsValidation/splitFilters.ts +82 -2
  99. package/types/dtos/types.d.ts +1 -0
  100. package/types/evaluator/index.d.ts +1 -0
  101. package/types/listeners/browser.d.ts +0 -1
  102. package/types/logger/constants.d.ts +5 -0
  103. package/types/myLogger.d.ts +5 -0
  104. package/types/sdkClient/clientAttributesDecoration.d.ts +4 -0
  105. package/types/sdkClient/types.d.ts +18 -0
  106. package/types/storages/AbstractSplitsCacheAsync.d.ts +2 -0
  107. package/types/storages/AbstractSplitsCacheSync.d.ts +2 -0
  108. package/types/storages/KeyBuilder.d.ts +1 -0
  109. package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +6 -1
  110. package/types/storages/inMemory/CountsCacheInMemory.d.ts +20 -0
  111. package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +20 -0
  112. package/types/storages/inMemory/SplitsCacheInMemory.d.ts +9 -1
  113. package/types/storages/inRedis/CountsCacheInRedis.d.ts +9 -0
  114. package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +9 -0
  115. package/types/storages/inRedis/SplitsCacheInRedis.d.ts +8 -0
  116. package/types/storages/metadataBuilder.d.ts +3 -0
  117. package/types/storages/pluggable/SplitsCachePluggable.d.ts +8 -0
  118. package/types/storages/types.d.ts +4 -0
  119. package/types/sync/offline/LocalhostFromFile.d.ts +2 -0
  120. package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -0
  121. package/types/sync/offline/updaters/splitChangesUpdater.d.ts +0 -0
  122. package/types/sync/polling/updaters/splitChangesUpdater.d.ts +3 -3
  123. package/types/sync/submitters/eventsSyncTask.d.ts +8 -0
  124. package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +5 -0
  125. package/types/sync/submitters/impressionCountsSyncTask.d.ts +13 -0
  126. package/types/sync/submitters/impressionsSyncTask.d.ts +14 -0
  127. package/types/sync/submitters/metricsSyncTask.d.ts +12 -0
  128. package/types/sync/submitters/submitterSyncTask.d.ts +10 -0
  129. package/types/sync/submitters/types.d.ts +7 -1
  130. package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +5 -0
  131. package/types/sync/syncTaskComposite.d.ts +5 -0
  132. package/types/trackers/filter/bloomFilter.d.ts +10 -0
  133. package/types/trackers/filter/dictionaryFilter.d.ts +8 -0
  134. package/types/trackers/filter/types.d.ts +5 -0
  135. package/types/types.d.ts +118 -1
  136. package/types/utils/constants/index.d.ts +4 -0
  137. package/types/utils/lang/sets.d.ts +1 -0
  138. package/types/utils/settingsValidation/splitFilters.d.ts +1 -0
  139. package/types/utils/timeTracker/index.d.ts +70 -0
  140. package/types/sdkClient/identity.d.ts +0 -6
  141. package/types/utils/inputValidation/sdkKey.d.ts +0 -7
  142. /package/types/storages/inMemory/{UniqueKeysCacheInMemory.d.ts → uniqueKeysCacheInMemory.d.ts} +0 -0
  143. /package/types/storages/inMemory/{UniqueKeysCacheInMemoryCS.d.ts → uniqueKeysCacheInMemoryCS.d.ts} +0 -0
  144. /package/types/storages/inRedis/{UniqueKeysCacheInRedis.d.ts → uniqueKeysCacheInRedis.d.ts} +0 -0
@@ -1,12 +1,13 @@
1
1
  import { _Set, setToArray, ISet } from '../../../utils/lang/sets';
2
2
  import { ISegmentsCacheBase, ISplitsCacheBase } from '../../../storages/types';
3
3
  import { ISplitChangesFetcher } from '../fetchers/types';
4
- import { ISplit, ISplitChangesResponse } from '../../../dtos/types';
4
+ import { ISplit, ISplitChangesResponse, ISplitFiltersValidation } from '../../../dtos/types';
5
5
  import { ISplitsEventEmitter } from '../../../readiness/types';
6
6
  import { timeout } from '../../../utils/promise/timeout';
7
7
  import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../../../readiness/constants';
8
8
  import { ILogger } from '../../../logger/types';
9
9
  import { SYNC_SPLITS_FETCH, SYNC_SPLITS_NEW, SYNC_SPLITS_REMOVED, SYNC_SPLITS_SEGMENTS, SYNC_SPLITS_FETCH_FAILS, SYNC_SPLITS_FETCH_RETRY } from '../../../logger/constants';
10
+ import { startsWith } from '../../../utils/lang';
10
11
 
11
12
  type ISplitChangesUpdater = (noCache?: boolean, till?: number, splitUpdateNotification?: { payload: ISplit, changeNumber: number }) => Promise<boolean>
12
13
 
@@ -45,15 +46,36 @@ interface ISplitMutations {
45
46
  segments: string[]
46
47
  }
47
48
 
49
+ /**
50
+ * If there are defined filters and one feature flag doesn't match with them, its status is changed to 'ARCHIVE' to avoid storing it
51
+ * If there are set filter defined, names filter is ignored
52
+ *
53
+ * @param featureFlag feature flag to be evaluated
54
+ * @param filters splitFiltersValidation bySet | byName
55
+ */
56
+ function matchFilters(featureFlag: ISplit, filters: ISplitFiltersValidation) {
57
+ const { bySet: setsFilter, byName: namesFilter, byPrefix: prefixFilter} = filters.groupedFilters;
58
+ if (setsFilter.length > 0) return featureFlag.sets && featureFlag.sets.some((featureFlagSet: string) => setsFilter.indexOf(featureFlagSet) > -1);
59
+
60
+ const namesFilterConfigured = namesFilter.length > 0;
61
+ const prefixFilterConfigured = prefixFilter.length > 0;
62
+
63
+ if (!namesFilterConfigured && !prefixFilterConfigured) return true;
64
+
65
+ const matchNames = namesFilterConfigured && namesFilter.indexOf(featureFlag.name) > -1;
66
+ const matchPrefix = prefixFilterConfigured && prefixFilter.some(prefix => startsWith(featureFlag.name, prefix));
67
+ return matchNames || matchPrefix;
68
+ }
69
+
48
70
  /**
49
71
  * Given the list of splits from /splitChanges endpoint, it returns the mutations,
50
72
  * i.e., an object with added splits, removed splits and used segments.
51
73
  * Exported for testing purposes.
52
74
  */
53
- export function computeSplitsMutation(entries: ISplit[]): ISplitMutations {
75
+ export function computeSplitsMutation(entries: ISplit[], filters: ISplitFiltersValidation): ISplitMutations {
54
76
  const segments = new _Set<string>();
55
77
  const computed = entries.reduce((accum, split) => {
56
- if (split.status === 'ACTIVE') {
78
+ if (split.status === 'ACTIVE' && matchFilters(split, filters)) {
57
79
  accum.added.push([split.name, split]);
58
80
 
59
81
  parseSegments(split).forEach((segmentName: string) => {
@@ -90,6 +112,7 @@ export function splitChangesUpdaterFactory(
90
112
  splitChangesFetcher: ISplitChangesFetcher,
91
113
  splits: ISplitsCacheBase,
92
114
  segments: ISegmentsCacheBase,
115
+ splitFiltersValidation: ISplitFiltersValidation,
93
116
  splitsEventEmitter?: ISplitsEventEmitter,
94
117
  requestTimeoutBeforeReady: number = 0,
95
118
  retriesOnFailureBeforeReady: number = 0,
@@ -126,7 +149,7 @@ export function splitChangesUpdaterFactory(
126
149
  .then((splitChanges: ISplitChangesResponse) => {
127
150
  startingUp = false;
128
151
 
129
- const mutation = computeSplitsMutation(splitChanges.splits);
152
+ const mutation = computeSplitsMutation(splitChanges.splits, splitFiltersValidation);
130
153
 
131
154
  log.debug(SYNC_SPLITS_NEW, [mutation.added.length]);
132
155
  log.debug(SYNC_SPLITS_REMOVED, [mutation.removed.length]);
@@ -11,6 +11,7 @@ function Uint8ArrayToString(myUint8Arr: Uint8Array) { // @ts-ignore
11
11
 
12
12
  function StringToUint8Array(myString: string) {
13
13
  const charCodes = myString.split('').map((e) => e.charCodeAt(0));
14
+ // eslint-disable-next-line compat/compat
14
15
  return new Uint8Array(charCodes);
15
16
  }
16
17
 
@@ -3,12 +3,13 @@ import { submitterFactory, firstPushWindowDecorator } from './submitter';
3
3
  import { TelemetryConfigStatsPayload, TelemetryConfigStats } from './types';
4
4
  import { CONSUMER_MODE, CONSUMER_ENUM, STANDALONE_MODE, CONSUMER_PARTIAL_MODE, STANDALONE_ENUM, CONSUMER_PARTIAL_ENUM, OPTIMIZED, DEBUG, NONE, DEBUG_ENUM, OPTIMIZED_ENUM, NONE_ENUM, CONSENT_GRANTED, CONSENT_DECLINED, CONSENT_UNKNOWN } from '../../utils/constants';
5
5
  import { SDK_READY, SDK_READY_FROM_CACHE } from '../../readiness/constants';
6
- import { ConsentStatus, ISettings, SDKMode } from '../../types';
6
+ import { ConsentStatus, ISettings, SDKMode, SplitIO } from '../../types';
7
7
  import { base } from '../../utils/settingsValidation';
8
8
  import { usedKeysMap } from '../../utils/inputValidation/apiKey';
9
9
  import { timer } from '../../utils/timeTracker/timer';
10
10
  import { ISdkFactoryContextSync } from '../../sdkFactory/types';
11
11
  import { objectAssign } from '../../utils/lang/objectAssign';
12
+ import { ISplitFiltersValidation } from '../../dtos/types';
12
13
 
13
14
  const OPERATION_MODE_MAP = {
14
15
  [STANDALONE_MODE]: STANDALONE_ENUM,
@@ -38,6 +39,18 @@ function getRedundantActiveFactories() {
38
39
  }, 0);
39
40
  }
40
41
 
42
+ function getTelemetryFlagSetsStats(splitFiltersValidation: ISplitFiltersValidation) {
43
+ // Group every configured flag set in an unique array called originalSets
44
+ let flagSetsTotal = 0;
45
+ splitFiltersValidation.validFilters.forEach((filter: SplitIO.SplitFilter) => {
46
+ if (filter.type === 'bySet') flagSetsTotal += filter.values.length;
47
+ });
48
+
49
+ const flagSetsValid = splitFiltersValidation.groupedFilters.bySet.length;
50
+ const flagSetsIgnored = flagSetsTotal - flagSetsValid;
51
+ return { flagSetsTotal, flagSetsIgnored };
52
+ }
53
+
41
54
  export function getTelemetryConfigStats(mode: SDKMode, storageType: string): TelemetryConfigStats {
42
55
  return {
43
56
  oM: OPERATION_MODE_MAP[mode], // @ts-ignore lower case of storage type
@@ -59,6 +72,8 @@ export function telemetryCacheConfigAdapter(telemetry: ITelemetryCacheSync, sett
59
72
  const { urls, scheduler } = settings;
60
73
  const isClientSide = settings.core.key !== undefined;
61
74
 
75
+ const { flagSetsTotal, flagSetsIgnored } = getTelemetryFlagSetsStats(settings.sync.__splitFiltersValidation);
76
+
62
77
  return objectAssign(getTelemetryConfigStats(settings.mode, settings.storage.type), {
63
78
  sE: settings.streamingEnabled,
64
79
  rR: {
@@ -86,7 +101,9 @@ export function telemetryCacheConfigAdapter(telemetry: ITelemetryCacheSync, sett
86
101
  nR: telemetry.getNonReadyUsage(),
87
102
  t: telemetry.popTags(),
88
103
  i: settings.integrations && settings.integrations.map(int => int.type),
89
- uC: settings.userConsent ? USER_CONSENT_MAP[settings.userConsent] : 0
104
+ uC: settings.userConsent ? USER_CONSENT_MAP[settings.userConsent] : 0,
105
+ fsT: flagSetsTotal,
106
+ fsI: flagSetsIgnored
90
107
  });
91
108
  }
92
109
  };
@@ -124,7 +124,11 @@ export type TREATMENTS = 'ts';
124
124
  export type TREATMENT_WITH_CONFIG = 'tc';
125
125
  export type TREATMENTS_WITH_CONFIG = 'tcs';
126
126
  export type TRACK = 'tr';
127
- export type Method = TREATMENT | TREATMENTS | TREATMENT_WITH_CONFIG | TREATMENTS_WITH_CONFIG | TRACK;
127
+ export type TREATMENTS_BY_FLAGSET = 'tf'
128
+ export type TREATMENTS_BY_FLAGSETS = 'tfs'
129
+ export type TREATMENTS_WITH_CONFIG_BY_FLAGSET = 'tcf'
130
+ export type TREATMENTS_WITH_CONFIG_BY_FLAGSETS = 'tcfs'
131
+ export type Method = TREATMENT | TREATMENTS | TREATMENT_WITH_CONFIG | TREATMENTS_WITH_CONFIG | TRACK | TREATMENTS_BY_FLAGSET | TREATMENTS_BY_FLAGSETS | TREATMENTS_WITH_CONFIG_BY_FLAGSET | TREATMENTS_WITH_CONFIG_BY_FLAGSETS;
128
132
 
129
133
  export type MethodLatencies = Partial<Record<Method, Array<number>>>;
130
134
 
@@ -234,6 +238,8 @@ export type TelemetryConfigStatsPayload = TelemetryConfigStats & {
234
238
  nR: number, // SDKNotReadyUsage
235
239
  i?: Array<string>, // integrations
236
240
  uC: number, // userConsent
241
+ fsT: number, // flagSetsTotal
242
+ fsI: number, // flagSetsInvalid
237
243
  }
238
244
 
239
245
  export interface ISubmitterManager extends ISyncTask {
package/src/types.ts CHANGED
@@ -610,6 +610,11 @@ export namespace SplitIO {
610
610
  configs: {
611
611
  [treatmentName: string]: string
612
612
  }
613
+ /**
614
+ * list of sets per feature flag
615
+ * @property {string[]} sets
616
+ */
617
+ sets?: string[]
613
618
  };
614
619
  /**
615
620
  * A promise that resolves to a feature flag view.
@@ -709,7 +714,7 @@ export namespace SplitIO {
709
714
  * SplitFilter type.
710
715
  * @typedef {string} SplitFilterType
711
716
  */
712
- export type SplitFilterType = 'byName' | 'byPrefix';
717
+ export type SplitFilterType = 'byName' | 'byPrefix' | 'bySet';
713
718
  /**
714
719
  * Defines a feature flag filter, described by a type and list of values.
715
720
  */
@@ -1059,6 +1064,42 @@ export namespace SplitIO {
1059
1064
  * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects
1060
1065
  */
1061
1066
  getTreatmentsWithConfig(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): TreatmentsWithConfig,
1067
+ /**
1068
+ * Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flagSet.
1069
+ * @function getTreatmentsByFlagSet
1070
+ * @param {string} key - The string key representing the consumer.
1071
+ * @param {string} flagSet - The flagSet name we want to get the treatments.
1072
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1073
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1074
+ */
1075
+ getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): Treatments,
1076
+ /**
1077
+ * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flagSets.
1078
+ * @function getTreatmentsWithConfigByFlagSet
1079
+ * @param {string} key - The string key representing the consumer.
1080
+ * @param {string} flagSet - The flagSet name we want to get the treatments.
1081
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1082
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1083
+ */
1084
+ getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): TreatmentsWithConfig,
1085
+ /**
1086
+ * Returns a Returns a Treatments value, which is an object with both treatment and config string for to the feature flags related to the given flagSets.
1087
+ * @function getTreatmentsByFlagSets
1088
+ * @param {string} key - The string key representing the consumer.
1089
+ * @param {Array<string>} flagSets - An array of the flagSet names we want to get the treatments.
1090
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1091
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1092
+ */
1093
+ getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): Treatments,
1094
+ /**
1095
+ * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flagSets.
1096
+ * @function getTreatmentsWithConfigByFlagSets
1097
+ * @param {string} key - The string key representing the consumer.
1098
+ * @param {Array<string>} flagSets - An array of the flagSet names we want to get the treatments.
1099
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1100
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1101
+ */
1102
+ getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): TreatmentsWithConfig,
1062
1103
  /**
1063
1104
  * Tracks an event to be fed to the results product on Split user interface.
1064
1105
  * @function track
@@ -1119,6 +1160,46 @@ export namespace SplitIO {
1119
1160
  * @returns {AsyncTreatmentsWithConfig} TreatmentsWithConfig promise that resolves to the map of TreatmentsWithConfig objects.
1120
1161
  */
1121
1162
  getTreatmentsWithConfig(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): AsyncTreatmentsWithConfig,
1163
+ /**
1164
+ * Returns a Treatments value, which will be (or eventually be) an object map with the treatments for the features related to the given flag set.
1165
+ * For usage on NodeJS as we don't have only one key.
1166
+ * @function getTreatmentsByFlagSet
1167
+ * @param {string} key - The string key representing the consumer.
1168
+ * @param {string} flagSet - The flag set name we want to get the treatments.
1169
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1170
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1171
+ */
1172
+ getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): AsyncTreatments,
1173
+ /**
1174
+ * Returns a TreatmentWithConfig value, which will be (or eventually be) an object with both treatment and config string for features related to the given flag set.
1175
+ * For usage on NodeJS as we don't have only one key.
1176
+ * @function getTreatmentsWithConfigByFlagSet
1177
+ * @param {string} key - The string key representing the consumer.
1178
+ * @param {string} flagSet - The flag set name we want to get the treatments.
1179
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1180
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1181
+ */
1182
+ getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): AsyncTreatmentsWithConfig,
1183
+ /**
1184
+ * Returns a Treatments value, which will be (or eventually be) an object map with the treatments for the feature flags related to the given flag sets.
1185
+ * For usage on NodeJS as we don't have only one key.
1186
+ * @function getTreatmentsByFlagSets
1187
+ * @param {string} key - The string key representing the consumer.
1188
+ * @param {Array<string>} flagSets - An array of the flag set names we want to get the treatments.
1189
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1190
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1191
+ */
1192
+ getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): AsyncTreatments,
1193
+ /**
1194
+ * Returns a TreatmentWithConfig value, which will be (or eventually be) an object with both treatment and config string for the feature flags related to the given flag sets.
1195
+ * For usage on NodeJS as we don't have only one key.
1196
+ * @function getTreatmentsWithConfigByFlagSets
1197
+ * @param {string} key - The string key representing the consumer.
1198
+ * @param {Array<string>} flagSets - An array of the flag set names we want to get the treatments.
1199
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1200
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1201
+ */
1202
+ getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): AsyncTreatmentsWithConfig,
1122
1203
  /**
1123
1204
  * Tracks an event to be fed to the results product on Split user interface, and returns a promise to signal when the event was successfully queued (or not).
1124
1205
  * @function track
@@ -1169,6 +1250,42 @@ export namespace SplitIO {
1169
1250
  * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects
1170
1251
  */
1171
1252
  getTreatmentsWithConfig(featureFlagNames: string[], attributes?: Attributes): TreatmentsWithConfig,
1253
+ /**
1254
+ * Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flag set.
1255
+ * @function getTreatmentsByFlagSet
1256
+ * @param {string} key - The string key representing the consumer.
1257
+ * @param {string} flagSet - The flag set name we want to get the treatments.
1258
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1259
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1260
+ */
1261
+ getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): Treatments,
1262
+ /**
1263
+ * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag set.
1264
+ * @function getTreatmentsWithConfigByFlagSet
1265
+ * @param {string} key - The string key representing the consumer.
1266
+ * @param {string} flagSet - The flag set name we want to get the treatments.
1267
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1268
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1269
+ */
1270
+ getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): TreatmentsWithConfig,
1271
+ /**
1272
+ * Returns a Returns a Treatments value, which is an object with both treatment and config string for to the feature flags related to the given flag sets.
1273
+ * @function getTreatmentsByFlagSets
1274
+ * @param {string} key - The string key representing the consumer.
1275
+ * @param {Array<string>} flagSets - An array of the flag set names we want to get the treatments.
1276
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1277
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1278
+ */
1279
+ getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): Treatments,
1280
+ /**
1281
+ * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag sets.
1282
+ * @function getTreatmentsWithConfigByFlagSets
1283
+ * @param {string} key - The string key representing the consumer.
1284
+ * @param {Array<string>} flagSets - An array of the flag set names we want to get the treatments.
1285
+ * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
1286
+ * @returns {Treatments} The map with all the TreatmentWithConfig objects
1287
+ */
1288
+ getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): TreatmentsWithConfig,
1172
1289
  /**
1173
1290
  * Tracks an event to be fed to the results product on Split user interface.
1174
1291
  * @function track
@@ -65,6 +65,10 @@ export const TREATMENT = 't';
65
65
  export const TREATMENTS = 'ts';
66
66
  export const TREATMENT_WITH_CONFIG = 'tc';
67
67
  export const TREATMENTS_WITH_CONFIG = 'tcs';
68
+ export const TREATMENTS_BY_FLAGSET = 'tf';
69
+ export const TREATMENTS_BY_FLAGSETS = 'tfs';
70
+ export const TREATMENTS_WITH_CONFIG_BY_FLAGSET = 'tcf';
71
+ export const TREATMENTS_WITH_CONFIG_BY_FLAGSETS = 'tcfs';
68
72
  export const TRACK = 'tr';
69
73
 
70
74
  export const CONNECTION_ESTABLISHED = 0;
@@ -111,3 +111,11 @@ export function __getSetConstructor(): ISetConstructor {
111
111
  }
112
112
 
113
113
  export const _Set = __getSetConstructor();
114
+
115
+ export function returnSetsUnion<T>(set: ISet<T>, set2: ISet<T>): ISet<T> {
116
+ const result = new _Set(setToArray(set));
117
+ set2.forEach( value => {
118
+ result.add(value);
119
+ });
120
+ return result;
121
+ }
@@ -13,7 +13,7 @@ const PIPELINE_METHODS = ['rpush', 'hincrby'];
13
13
 
14
14
  export class RedisMock {
15
15
 
16
- private pipelineMethods: any = { exec: jest.fn(asyncFunction) }
16
+ private pipelineMethods: any = { exec: jest.fn(asyncFunction) };
17
17
 
18
18
  constructor() {
19
19
  IDENTITY_METHODS.forEach(method => {
@@ -3,11 +3,18 @@ import { validateSplits } from '../inputValidation/splits';
3
3
  import { ISplitFiltersValidation } from '../../dtos/types';
4
4
  import { SplitIO } from '../../types';
5
5
  import { ILogger } from '../../logger/types';
6
- import { WARN_SPLITS_FILTER_IGNORED, WARN_SPLITS_FILTER_EMPTY, WARN_SPLITS_FILTER_INVALID, SETTINGS_SPLITS_FILTER, LOG_PREFIX_SETTINGS } from '../../logger/constants';
6
+ import { WARN_SPLITS_FILTER_IGNORED, WARN_SPLITS_FILTER_EMPTY, WARN_SPLITS_FILTER_INVALID, SETTINGS_SPLITS_FILTER, LOG_PREFIX_SETTINGS, ERROR_SETS_FILTER_EXCLUSIVE, WARN_SPLITS_FILTER_LOWERCASE_SET, WARN_SPLITS_FILTER_INVALID_SET, ERROR_EMPTY_ARRAY, WARN_FLAGSET_NOT_CONFIGURED } from '../../logger/constants';
7
+ import { objectAssign } from '../lang/objectAssign';
8
+ import { find, uniq } from '../lang';
7
9
 
8
10
  // Split filters metadata.
9
11
  // Ordered according to their precedency when forming the filter query string: `&names=<values>&prefixes=<values>`
10
12
  const FILTERS_METADATA = [
13
+ {
14
+ type: 'bySet' as SplitIO.SplitFilterType,
15
+ maxLength: 50,
16
+ queryParam: 'sets='
17
+ },
11
18
  {
12
19
  type: 'byName' as SplitIO.SplitFilterType,
13
20
  maxLength: 400,
@@ -20,6 +27,9 @@ const FILTERS_METADATA = [
20
27
  }
21
28
  ];
22
29
 
30
+ const VALID_FLAGSET_REGEX = /^[a-z0-9][_a-z0-9]{0,49}$/;
31
+ const CAPITAL_LETTERS_REGEX = /[A-Z]/;
32
+
23
33
  /**
24
34
  * Validates that the given value is a valid filter type
25
35
  */
@@ -42,6 +52,11 @@ function validateSplitFilter(log: ILogger, type: SplitIO.SplitFilterType, values
42
52
  let result = validateSplits(log, values, LOG_PREFIX_SETTINGS, `${type} filter`, `${type} filter value`);
43
53
 
44
54
  if (result) {
55
+
56
+ if (type === 'bySet') {
57
+ result = sanitizeFlagSets(log, result);
58
+ }
59
+
45
60
  // check max length
46
61
  if (result.length > maxLength) throw new Error(`${maxLength} unique values can be specified at most for '${type}' filter. You passed ${result.length}. Please consider reducing the amount or using other filter.`);
47
62
 
@@ -72,6 +87,43 @@ function queryStringBuilder(groupedFilters: Record<SplitIO.SplitFilterType, stri
72
87
  return queryParams.length > 0 ? '&' + queryParams.join('&') : null;
73
88
  }
74
89
 
90
+ /**
91
+ * Sanitizes set names list taking in account:
92
+ * - It should be lowercase
93
+ * - Must adhere the following regular expression /^[a-z0-9][_a-z0-9]{0,49}$/ that means
94
+ * - must start with a letter or number
95
+ * - Be in lowercase
96
+ * - Be alphanumeric
97
+ * - have a max length of 50 characters
98
+ *
99
+ * @param {ILogger} log
100
+ * @param {string[]} flagSets
101
+ * @returns sanitized list of set names
102
+ */
103
+ function sanitizeFlagSets(log: ILogger, flagSets: string[]) {
104
+ let sanitizedSets = flagSets
105
+ .map(flagSet => {
106
+ if (CAPITAL_LETTERS_REGEX.test(flagSet)){
107
+ log.warn(WARN_SPLITS_FILTER_LOWERCASE_SET,[flagSet]);
108
+ flagSet = flagSet.toLowerCase();
109
+ }
110
+ return flagSet;
111
+ })
112
+ .filter(flagSet => {
113
+ if (!VALID_FLAGSET_REGEX.test(flagSet)){
114
+ log.warn(WARN_SPLITS_FILTER_INVALID_SET, [flagSet,VALID_FLAGSET_REGEX,flagSet]);
115
+ return false;
116
+ }
117
+ if (typeof flagSet !== 'string') return false;
118
+ return true;
119
+ });
120
+ return uniq(sanitizedSets);
121
+ }
122
+
123
+ function configuredFilter(validFilters: SplitIO.SplitFilter[], filterType: SplitIO.SplitFilterType) {
124
+ return find(validFilters, (filter: SplitIO.SplitFilter) => filter.type === filterType && filter.values.length > 0);
125
+ }
126
+
75
127
  /**
76
128
  * Validates `splitFilters` configuration object and parses it into a query string for filtering splits on `/splitChanges` fetch.
77
129
  *
@@ -90,7 +142,7 @@ export function validateSplitFilters(log: ILogger, maybeSplitFilters: any, mode:
90
142
  const res = {
91
143
  validFilters: [],
92
144
  queryString: null,
93
- groupedFilters: { byName: [], byPrefix: [] }
145
+ groupedFilters: { bySet: [], byName: [], byPrefix: [] },
94
146
  } as ISplitFiltersValidation;
95
147
 
96
148
  // do nothing if `splitFilters` param is not a non-empty array or mode is not STANDALONE
@@ -122,9 +174,37 @@ export function validateSplitFilters(log: ILogger, maybeSplitFilters: any, mode:
122
174
  if (res.groupedFilters[type].length > 0) res.groupedFilters[type] = validateSplitFilter(log, type, res.groupedFilters[type], maxLength);
123
175
  });
124
176
 
177
+ const setFilter = configuredFilter(res.validFilters, 'bySet');
178
+ // Clean all filters if set filter is present
179
+ if (setFilter) {
180
+ if (configuredFilter(res.validFilters, 'byName') || configuredFilter(res.validFilters, 'byPrefix')) log.error(ERROR_SETS_FILTER_EXCLUSIVE);
181
+ objectAssign(res.groupedFilters, { byName: [], byPrefix: [] });
182
+ }
183
+
125
184
  // build query string
126
185
  res.queryString = queryStringBuilder(res.groupedFilters);
127
186
  log.debug(SETTINGS_SPLITS_FILTER, [res.queryString]);
128
187
 
129
188
  return res;
130
189
  }
190
+
191
+ export function flagSetsAreValid(log: ILogger, method: string, flagSets: string[], flagSetsInConfig: string[]): string[] {
192
+ let toReturn: string[] = [];
193
+ if (flagSets.length === 0) {
194
+ log.error(ERROR_EMPTY_ARRAY, [method, 'flagSets']);
195
+ return toReturn;
196
+ }
197
+ const sets = validateSplits(log, flagSets, method, 'flag sets', 'flag set');
198
+ toReturn = sets ? sanitizeFlagSets(log, sets) : [];
199
+ if (flagSetsInConfig.length > 0) {
200
+ toReturn = toReturn.filter(flagSet => {
201
+ if (flagSetsInConfig.indexOf(flagSet) > -1) {
202
+ return true;
203
+ }
204
+ log.warn(WARN_FLAGSET_NOT_CONFIGURED, [flagSet]);
205
+ return false;
206
+ });
207
+ }
208
+
209
+ return toReturn;
210
+ }
@@ -132,6 +132,7 @@ export interface ISplit {
132
132
  configurations?: {
133
133
  [treatmentName: string]: string;
134
134
  };
135
+ sets?: string[];
135
136
  }
136
137
  export declare type ISplitPartial = Pick<ISplit, 'conditions' | 'configurations' | 'trafficTypeName'>;
137
138
  /** Interface of the parsed JSON response of `/splitChanges` */
@@ -5,3 +5,4 @@ import { SplitIO } from '../types';
5
5
  import { ILogger } from '../logger/types';
6
6
  export declare function evaluateFeature(log: ILogger, key: SplitIO.SplitKey, splitName: string, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync): MaybeThenable<IEvaluationResult>;
7
7
  export declare function evaluateFeatures(log: ILogger, key: SplitIO.SplitKey, splitNames: string[], attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync): MaybeThenable<Record<string, IEvaluationResult>>;
8
+ export declare function evaluateFeaturesByFlagSets(log: ILogger, key: SplitIO.SplitKey, flagSets: string[], attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync): MaybeThenable<Record<string, IEvaluationResult>>;
@@ -23,7 +23,6 @@ export declare class BrowserSignalListener implements ISignalListener {
23
23
  * Called when client is destroyed, it removes event listeners.
24
24
  */
25
25
  stop(): void;
26
- stopSync(): void;
27
26
  /**
28
27
  * flushData method.
29
28
  * Called when pagehide event is triggered. It flushed remaining impressions and events to the backend,
@@ -95,6 +95,9 @@ export declare const WARN_SPLITS_FILTER_EMPTY = 221;
95
95
  export declare const WARN_SDK_KEY = 222;
96
96
  export declare const STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 223;
97
97
  export declare const STREAMING_PARSING_SPLIT_UPDATE = 224;
98
+ export declare const WARN_SPLITS_FILTER_INVALID_SET = 225;
99
+ export declare const WARN_SPLITS_FILTER_LOWERCASE_SET = 226;
100
+ export declare const WARN_FLAGSET_NOT_CONFIGURED = 227;
98
101
  export declare const ERROR_ENGINE_COMBINER_IFELSEIF = 300;
99
102
  export declare const ERROR_LOGLEVEL_INVALID = 301;
100
103
  export declare const ERROR_CLIENT_LISTENER = 302;
@@ -122,6 +125,8 @@ export declare const ERROR_LOCALHOST_MODULE_REQUIRED = 323;
122
125
  export declare const ERROR_STORAGE_INVALID = 324;
123
126
  export declare const ERROR_NOT_BOOLEAN = 325;
124
127
  export declare const ERROR_MIN_CONFIG_PARAM = 326;
128
+ export declare const ERROR_TOO_MANY_SETS = 327;
129
+ export declare const ERROR_SETS_FILTER_EXCLUSIVE = 328;
125
130
  export declare const LOG_PREFIX_SETTINGS = "settings";
126
131
  export declare const LOG_PREFIX_INSTANTIATION = "Factory instantiation";
127
132
  export declare const LOG_PREFIX_ENGINE = "engine";
@@ -0,0 +1,5 @@
1
+ export declare const myLogger: {
2
+ log: (msg: any) => void;
3
+ logCsv: (msg: any) => void;
4
+ logToFile: (file: any, msg: any) => void;
5
+ };
@@ -8,6 +8,10 @@ export declare function clientAttributesDecoration<TClient extends SplitIO.IClie
8
8
  getTreatmentWithConfig: (maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.TreatmentWithConfig | SplitIO.AsyncTreatmentWithConfig;
9
9
  getTreatments: (maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.Treatments | SplitIO.AsyncTreatments;
10
10
  getTreatmentsWithConfig: (maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.TreatmentsWithConfig | SplitIO.AsyncTreatmentsWithConfig;
11
+ getTreatmentsByFlagSets: (maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.Treatments | SplitIO.AsyncTreatments;
12
+ getTreatmentsWithConfigByFlagSets: (maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.TreatmentsWithConfig | SplitIO.AsyncTreatmentsWithConfig;
13
+ getTreatmentsByFlagSet: (maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.Treatments | SplitIO.AsyncTreatments;
14
+ getTreatmentsWithConfigByFlagSet: (maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.TreatmentsWithConfig | SplitIO.AsyncTreatmentsWithConfig;
11
15
  track: (maybeKey: SplitIO.SplitKey, maybeTT: string, maybeEvent: string, maybeEventValue?: number | undefined, maybeProperties?: SplitIO.Properties | undefined) => boolean | Promise<boolean>;
12
16
  /**
13
17
  * Add an attribute to client's in memory attributes storage
@@ -0,0 +1,18 @@
1
+ import { ISignalListener } from '../listeners/types';
2
+ import { ISdkReadinessManager } from '../readiness/types';
3
+ import { IStorageAsync, IStorageSync } from '../storages/types';
4
+ import { ISyncManager } from '../sync/types';
5
+ import { IEventTracker, IImpressionsTracker } from '../trackers/types';
6
+ import { ISettings } from '../types';
7
+ export interface IClientFactoryParams {
8
+ storage: IStorageSync | IStorageAsync;
9
+ sdkReadinessManager: ISdkReadinessManager;
10
+ settings: ISettings;
11
+ impressionsTracker: IImpressionsTracker;
12
+ eventTracker: IEventTracker;
13
+ }
14
+ export interface ISdkClientFactoryParams extends IClientFactoryParams {
15
+ signalListener?: ISignalListener;
16
+ syncManager?: ISyncManager;
17
+ sharedClient?: boolean;
18
+ }
@@ -1,5 +1,6 @@
1
1
  import { ISplitsCacheAsync } from './types';
2
2
  import { ISplit } from '../dtos/types';
3
+ import { ISet } from '../utils/lang/sets';
3
4
  /**
4
5
  * This class provides a skeletal implementation of the ISplitsCacheAsync interface
5
6
  * to minimize the effort required to implement this interface.
@@ -14,6 +15,7 @@ export declare abstract class AbstractSplitsCacheAsync implements ISplitsCacheAs
14
15
  abstract getChangeNumber(): Promise<number>;
15
16
  abstract getAll(): Promise<ISplit[]>;
16
17
  abstract getSplitNames(): Promise<string[]>;
18
+ abstract getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>>;
17
19
  abstract trafficTypeExists(trafficType: string): Promise<boolean>;
18
20
  abstract clear(): Promise<boolean | void>;
19
21
  usesSegments(): Promise<boolean>;
@@ -1,5 +1,6 @@
1
1
  import { ISplitsCacheSync } from './types';
2
2
  import { ISplit } from '../dtos/types';
3
+ import { ISet } from '../utils/lang/sets';
3
4
  /**
4
5
  * This class provides a skeletal implementation of the ISplitsCacheSync interface
5
6
  * to minimize the effort required to implement this interface.
@@ -34,6 +35,7 @@ export declare abstract class AbstractSplitsCacheSync implements ISplitsCacheSyn
34
35
  * for instance, if the `changeNumber` is old, or if the split is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
35
36
  */
36
37
  killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean;
38
+ abstract getNamesByFlagSets(flagSets: string[]): ISet<string>;
37
39
  }
38
40
  /**
39
41
  * Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
@@ -3,6 +3,7 @@ export declare class KeyBuilder {
3
3
  protected readonly prefix: string;
4
4
  constructor(prefix?: string);
5
5
  buildTrafficTypeKey(trafficType: string): string;
6
+ buildFlagSetKey(flagSet: string): string;
6
7
  buildSplitKey(splitName: string): string;
7
8
  buildSplitsTillKey(): string;
8
9
  isSplitKey(key: string): boolean;
@@ -2,6 +2,7 @@ import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
2
2
  import { AbstractSplitsCacheSync } from '../AbstractSplitsCacheSync';
3
3
  import { KeyBuilderCS } from '../KeyBuilderCS';
4
4
  import { ILogger } from '../../logger/types';
5
+ import { ISet } from '../../utils/lang/sets';
5
6
  /**
6
7
  * ISplitsCacheSync implementation that stores split definitions in browser LocalStorage.
7
8
  */
@@ -9,8 +10,8 @@ export declare class SplitsCacheInLocal extends AbstractSplitsCacheSync {
9
10
  private readonly log;
10
11
  private readonly keys;
11
12
  private readonly splitFiltersValidation;
13
+ private readonly flagSetsFilter;
12
14
  private hasSync?;
13
- private cacheReadyButNeedsToFlush;
14
15
  private updateNewFilter?;
15
16
  /**
16
17
  * @param {KeyBuilderCS} keys
@@ -47,4 +48,8 @@ export declare class SplitsCacheInLocal extends AbstractSplitsCacheSync {
47
48
  */
48
49
  private _checkExpiration;
49
50
  private _checkFilterQuery;
51
+ getNamesByFlagSets(flagSets: string[]): ISet<string>;
52
+ private addToFlagSets;
53
+ private removeFromFlagSets;
54
+ private removeNames;
50
55
  }
@@ -0,0 +1,20 @@
1
+ import { ICountsCacheSync } from '../types';
2
+ export declare class CountsCacheInMemory implements ICountsCacheSync {
3
+ private counters;
4
+ /**
5
+ * Add counts.
6
+ */
7
+ track(metricName: string): boolean;
8
+ /**
9
+ * Clear the collector
10
+ */
11
+ clear(): void;
12
+ /**
13
+ * Get the collected data, used as payload for posting.
14
+ */
15
+ state(): Record<string, number>;
16
+ /**
17
+ * Check if the cache is empty.
18
+ */
19
+ isEmpty(): boolean;
20
+ }