@splitsoftware/splitio-commons 1.12.1-rc.1 → 1.12.1-rc.3

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 (58) hide show
  1. package/CHANGES.txt +11 -9
  2. package/cjs/sdkClient/client.js +4 -4
  3. package/cjs/sdkFactory/index.js +1 -1
  4. package/cjs/sdkManager/index.js +9 -6
  5. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +1 -3
  6. package/cjs/storages/inRedis/RedisAdapter.js +32 -13
  7. package/cjs/storages/inRedis/SegmentsCacheInRedis.js +2 -2
  8. package/cjs/storages/inRedis/SplitsCacheInRedis.js +15 -15
  9. package/cjs/storages/pluggable/SplitsCachePluggable.js +5 -5
  10. package/cjs/utils/inputValidation/index.js +5 -5
  11. package/cjs/utils/inputValidation/{splitExistance.js → splitExistence.js} +3 -3
  12. package/cjs/utils/inputValidation/{trafficTypeExistance.js → trafficTypeExistence.js} +6 -6
  13. package/esm/sdkClient/client.js +4 -4
  14. package/esm/sdkFactory/index.js +1 -1
  15. package/esm/sdkManager/index.js +10 -7
  16. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +1 -3
  17. package/esm/storages/inRedis/RedisAdapter.js +32 -13
  18. package/esm/storages/inRedis/SegmentsCacheInRedis.js +2 -2
  19. package/esm/storages/inRedis/SplitsCacheInRedis.js +15 -15
  20. package/esm/storages/pluggable/SplitsCachePluggable.js +5 -5
  21. package/esm/utils/inputValidation/index.js +2 -2
  22. package/esm/utils/inputValidation/{splitExistance.js → splitExistence.js} +1 -1
  23. package/esm/utils/inputValidation/{trafficTypeExistance.js → trafficTypeExistence.js} +4 -4
  24. package/package.json +1 -1
  25. package/src/sdkClient/client.ts +4 -4
  26. package/src/sdkFactory/index.ts +1 -1
  27. package/src/sdkFactory/types.ts +3 -7
  28. package/src/sdkManager/index.ts +13 -10
  29. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +4 -5
  30. package/src/storages/inRedis/EventsCacheInRedis.ts +3 -3
  31. package/src/storages/inRedis/ImpressionCountsCacheInRedis.ts +3 -3
  32. package/src/storages/inRedis/ImpressionsCacheInRedis.ts +3 -3
  33. package/src/storages/inRedis/RedisAdapter.ts +38 -16
  34. package/src/storages/inRedis/SegmentsCacheInRedis.ts +5 -5
  35. package/src/storages/inRedis/SplitsCacheInRedis.ts +18 -19
  36. package/src/storages/inRedis/TelemetryCacheInRedis.ts +2 -2
  37. package/src/storages/inRedis/UniqueKeysCacheInRedis.ts +3 -3
  38. package/src/storages/pluggable/SplitsCachePluggable.ts +5 -5
  39. package/src/trackers/impressionObserver/utils.ts +1 -1
  40. package/src/utils/inputValidation/index.ts +2 -2
  41. package/src/utils/inputValidation/{splitExistance.ts → splitExistence.ts} +1 -1
  42. package/src/utils/inputValidation/{trafficTypeExistance.ts → trafficTypeExistence.ts} +4 -4
  43. package/src/utils/redis/RedisMock.ts +1 -3
  44. package/types/sdkFactory/types.d.ts +3 -3
  45. package/types/sdkManager/index.d.ts +2 -3
  46. package/types/storages/inRedis/EventsCacheInRedis.d.ts +2 -2
  47. package/types/storages/inRedis/ImpressionCountsCacheInRedis.d.ts +3 -2
  48. package/types/storages/inRedis/ImpressionsCacheInRedis.d.ts +2 -2
  49. package/types/storages/inRedis/RedisAdapter.d.ts +1 -1
  50. package/types/storages/inRedis/SegmentsCacheInRedis.d.ts +3 -3
  51. package/types/storages/inRedis/SplitsCacheInRedis.d.ts +6 -11
  52. package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +2 -2
  53. package/types/storages/inRedis/UniqueKeysCacheInRedis.d.ts +3 -2
  54. package/types/storages/pluggable/SplitsCachePluggable.d.ts +4 -4
  55. package/types/trackers/impressionObserver/utils.d.ts +1 -1
  56. package/types/utils/inputValidation/index.d.ts +2 -2
  57. package/types/utils/inputValidation/splitExistence.d.ts +7 -0
  58. package/types/utils/inputValidation/trafficTypeExistence.d.ts +9 -0
@@ -1,17 +1,17 @@
1
- import { Redis } from 'ioredis';
2
1
  import { ILogger } from '../../logger/types';
3
2
  import { isNaNNumber } from '../../utils/lang';
4
3
  import { LOG_PREFIX } from '../inLocalStorage/constants';
5
4
  import { KeyBuilderSS } from '../KeyBuilderSS';
6
5
  import { ISegmentsCacheAsync } from '../types';
6
+ import type { RedisAdapter } from './RedisAdapter';
7
7
 
8
8
  export class SegmentsCacheInRedis implements ISegmentsCacheAsync {
9
9
 
10
10
  private readonly log: ILogger;
11
- private readonly redis: Redis;
11
+ private readonly redis: RedisAdapter;
12
12
  private readonly keys: KeyBuilderSS;
13
13
 
14
- constructor(log: ILogger, keys: KeyBuilderSS, redis: Redis) {
14
+ constructor(log: ILogger, keys: KeyBuilderSS, redis: RedisAdapter) {
15
15
  this.log = log;
16
16
  this.redis = redis;
17
17
  this.keys = keys;
@@ -72,8 +72,8 @@ export class SegmentsCacheInRedis implements ISegmentsCacheAsync {
72
72
  return this.redis.smembers(this.keys.buildRegisteredSegmentsKey());
73
73
  }
74
74
 
75
- // @TODO remove/review. It is not being used.
75
+ // @TODO remove or implement. It is not being used.
76
76
  clear() {
77
- return this.redis.flushdb().then(status => status === 'OK');
77
+ return Promise.resolve();
78
78
  }
79
79
  }
@@ -1,11 +1,11 @@
1
1
  import { isFiniteNumber, isNaNNumber } from '../../utils/lang';
2
2
  import { KeyBuilderSS } from '../KeyBuilderSS';
3
- import { Redis } from 'ioredis';
4
3
  import { ILogger } from '../../logger/types';
5
4
  import { LOG_PREFIX } from './constants';
6
5
  import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
7
6
  import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
8
7
  import { ISet, _Set, returnListDifference } from '../../utils/lang/sets';
8
+ import type { RedisAdapter } from './RedisAdapter';
9
9
 
10
10
  /**
11
11
  * Discard errors for an answer of multiple operations.
@@ -24,12 +24,12 @@ function processPipelineAnswer(results: Array<[Error | null, string]>): string[]
24
24
  export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
25
25
 
26
26
  private readonly log: ILogger;
27
- private readonly redis: Redis;
27
+ private readonly redis: RedisAdapter;
28
28
  private readonly keys: KeyBuilderSS;
29
29
  private redisError?: string;
30
30
  private readonly flagSetsFilter: string[];
31
31
 
32
- constructor(log: ILogger, keys: KeyBuilderSS, redis: Redis, splitFiltersValidation?: ISplitFiltersValidation) {
32
+ constructor(log: ILogger, keys: KeyBuilderSS, redis: RedisAdapter, splitFiltersValidation?: ISplitFiltersValidation) {
33
33
  super();
34
34
  this.log = log;
35
35
  this.redis = redis;
@@ -195,7 +195,7 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
195
195
  .then((listOfKeys) => this.redis.pipeline(listOfKeys.map(k => ['get', k])).exec())
196
196
  .then(processPipelineAnswer)
197
197
  .then((splitDefinitions) => splitDefinitions.map((splitDefinition) => {
198
- return JSON.parse(splitDefinition as string);
198
+ return JSON.parse(splitDefinition);
199
199
  }));
200
200
  }
201
201
 
@@ -211,15 +211,18 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
211
211
  }
212
212
 
213
213
  /**
214
- * Get list of split names related to a given flag set names list.
215
- * The returned promise is resolved with the list of split names,
216
- * or rejected if any wrapper operation fails.
214
+ * Get list of feature flag names related to a given list of flag set names.
215
+ * The returned promise is resolved with the list of feature flag names per flag set,
216
+ * or rejected if the pipelined redis operation fails (e.g., timeout).
217
217
  */
218
218
  getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>[]> {
219
- return Promise.all(flagSets.map(flagSet => {
220
- const flagSetKey = this.keys.buildFlagSetKey(flagSet);
221
- return this.redis.smembers(flagSetKey);
222
- })).then(namesByFlagSets => namesByFlagSets.map(namesByFlagSet => new _Set(namesByFlagSet)));
219
+ return this.redis.pipeline(flagSets.map(flagSet => ['smembers', this.keys.buildFlagSetKey(flagSet)])).exec()
220
+ .then((results) => results.map(([e, value], index) => {
221
+ if (e === null) return value;
222
+
223
+ this.log.error(LOG_PREFIX + `Could not read result from get members of flag set ${flagSets[index]} due to an error: ${e}`);
224
+ }))
225
+ .then(namesByFlagSets => namesByFlagSets.map(namesByFlagSet => new _Set(namesByFlagSet)));
223
226
  }
224
227
 
225
228
  /**
@@ -236,26 +239,22 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
236
239
 
237
240
  ttCount = parseInt(ttCount as string, 10);
238
241
  if (!isFiniteNumber(ttCount) || ttCount < 0) {
239
- this.log.info(LOG_PREFIX + `Could not validate traffic type existance of ${trafficType} due to data corruption of some sorts.`);
242
+ this.log.info(LOG_PREFIX + `Could not validate traffic type existence of ${trafficType} due to data corruption of some sorts.`);
240
243
  return false;
241
244
  }
242
245
 
243
246
  return ttCount > 0;
244
247
  })
245
248
  .catch(e => {
246
- this.log.error(LOG_PREFIX + `Could not validate traffic type existance of ${trafficType} due to an error: ${e}.`);
249
+ this.log.error(LOG_PREFIX + `Could not validate traffic type existence of ${trafficType} due to an error: ${e}.`);
247
250
  // If there is an error, bypass the validation so the event can get tracked.
248
251
  return true;
249
252
  });
250
253
  }
251
254
 
252
- /**
253
- * Delete everything in the current database.
254
- *
255
- * @NOTE documentation says it never fails.
256
- */
255
+ // @TODO remove or implement. It is not being used.
257
256
  clear() {
258
- return this.redis.flushdb().then(status => status === 'OK');
257
+ return Promise.resolve();
259
258
  }
260
259
 
261
260
  /**
@@ -3,13 +3,13 @@ import { Method, MultiConfigs, MultiMethodExceptions, MultiMethodLatencies } fro
3
3
  import { KeyBuilderSS } from '../KeyBuilderSS';
4
4
  import { ITelemetryCacheAsync } from '../types';
5
5
  import { findLatencyIndex } from '../findLatencyIndex';
6
- import { Redis } from 'ioredis';
7
6
  import { getTelemetryConfigStats } from '../../sync/submitters/telemetrySubmitter';
8
7
  import { CONSUMER_MODE, STORAGE_REDIS } from '../../utils/constants';
9
8
  import { isNaNNumber, isString } from '../../utils/lang';
10
9
  import { _Map } from '../../utils/lang/maps';
11
10
  import { MAX_LATENCY_BUCKET_COUNT, newBuckets } from '../inMemory/TelemetryCacheInMemory';
12
11
  import { parseLatencyField, parseExceptionField, parseMetadata } from '../utils';
12
+ import type { RedisAdapter } from './RedisAdapter';
13
13
 
14
14
  export class TelemetryCacheInRedis implements ITelemetryCacheAsync {
15
15
 
@@ -19,7 +19,7 @@ export class TelemetryCacheInRedis implements ITelemetryCacheAsync {
19
19
  * @param keys Key builder.
20
20
  * @param redis Redis client.
21
21
  */
22
- constructor(private readonly log: ILogger, private readonly keys: KeyBuilderSS, private readonly redis: Redis) { }
22
+ constructor(private readonly log: ILogger, private readonly keys: KeyBuilderSS, private readonly redis: RedisAdapter) { }
23
23
 
24
24
  recordLatency(method: Method, latencyMs: number) {
25
25
  const [key, field] = this.keys.buildLatencyKey(method, findLatencyIndex(latencyMs)).split('::');
@@ -1,21 +1,21 @@
1
1
  import { IUniqueKeysCacheBase } from '../types';
2
- import { Redis } from 'ioredis';
3
2
  import { UniqueKeysCacheInMemory } from '../inMemory/UniqueKeysCacheInMemory';
4
3
  import { setToArray } from '../../utils/lang/sets';
5
4
  import { DEFAULT_CACHE_SIZE, REFRESH_RATE, TTL_REFRESH } from './constants';
6
5
  import { LOG_PREFIX } from './constants';
7
6
  import { ILogger } from '../../logger/types';
8
7
  import { UniqueKeysItemSs } from '../../sync/submitters/types';
8
+ import type { RedisAdapter } from './RedisAdapter';
9
9
 
10
10
  export class UniqueKeysCacheInRedis extends UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
11
11
 
12
12
  private readonly log: ILogger;
13
13
  private readonly key: string;
14
- private readonly redis: Redis;
14
+ private readonly redis: RedisAdapter;
15
15
  private readonly refreshRate: number;
16
16
  private intervalId: any;
17
17
 
18
- constructor(log: ILogger, key: string, redis: Redis, uniqueKeysQueueSize = DEFAULT_CACHE_SIZE, refreshRate = REFRESH_RATE) {
18
+ constructor(log: ILogger, key: string, redis: RedisAdapter, uniqueKeysQueueSize = DEFAULT_CACHE_SIZE, refreshRate = REFRESH_RATE) {
19
19
  super(uniqueKeysQueueSize);
20
20
  this.log = log;
21
21
  this.key = key;
@@ -177,14 +177,14 @@ export class SplitsCachePluggable extends AbstractSplitsCacheAsync {
177
177
  }
178
178
 
179
179
  /**
180
- * Get list of split names related to a given flag set names list.
181
- * The returned promise is resolved with the list of split names,
182
- * or rejected if any wrapper operation fails.
183
- */
180
+ * Get list of feature flag names related to a given list of flag set names.
181
+ * The returned promise is resolved with the list of feature flag names per flag set.
182
+ * It never rejects (If there is a wrapper error for some flag set, an empty set is returned for it).
183
+ */
184
184
  getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>[]> {
185
185
  return Promise.all(flagSets.map(flagSet => {
186
186
  const flagSetKey = this.keys.buildFlagSetKey(flagSet);
187
- return this.wrapper.getItems(flagSetKey);
187
+ return this.wrapper.getItems(flagSetKey).catch(() => []);
188
188
  })).then(namesByFlagSets => namesByFlagSets.map(namesByFlagSet => new _Set(namesByFlagSet)));
189
189
  }
190
190
 
@@ -4,6 +4,6 @@ import { ISettings } from '../../types';
4
4
  /**
5
5
  * Storage is async if mode is consumer or partial consumer
6
6
  */
7
- export function isStorageSync(settings: ISettings) {
7
+ export function isStorageSync(settings: Pick<ISettings, 'mode'>) {
8
8
  return [CONSUMER_MODE, CONSUMER_PARTIAL_MODE].indexOf(settings.mode) === -1 ? true : false;
9
9
  }
@@ -8,6 +8,6 @@ export { validateSplit } from './split';
8
8
  export { validateSplits } from './splits';
9
9
  export { validateTrafficType } from './trafficType';
10
10
  export { validateIfNotDestroyed, validateIfOperational } from './isOperational';
11
- export { validateSplitExistance } from './splitExistance';
12
- export { validateTrafficTypeExistance } from './trafficTypeExistance';
11
+ export { validateSplitExistence } from './splitExistence';
12
+ export { validateTrafficTypeExistence } from './trafficTypeExistence';
13
13
  export { validatePreloadedData } from './preloadedData';
@@ -7,7 +7,7 @@ import { WARN_NOT_EXISTENT_SPLIT } from '../../logger/constants';
7
7
  * This is defined here and in this format mostly because of the logger and the fact that it's considered a validation at product level.
8
8
  * But it's not going to run on the input validation layer. In any case, the most compeling reason to use it as we do is to avoid going to Redis and get a split twice.
9
9
  */
10
- export function validateSplitExistance(log: ILogger, readinessManager: IReadinessManager, splitName: string, labelOrSplitObj: any, method: string): boolean {
10
+ export function validateSplitExistence(log: ILogger, readinessManager: IReadinessManager, splitName: string, labelOrSplitObj: any, method: string): boolean {
11
11
  if (readinessManager.isReady()) { // Only if it's ready we validate this, otherwise it may just be that the SDK is not ready yet.
12
12
  if (labelOrSplitObj === SPLIT_NOT_FOUND || labelOrSplitObj == null) {
13
13
  log.warn(WARN_NOT_EXISTENT_SPLIT, [method, splitName]);
@@ -7,14 +7,14 @@ import { MaybeThenable } from '../../dtos/types';
7
7
  import { ILogger } from '../../logger/types';
8
8
  import { WARN_NOT_EXISTENT_TT } from '../../logger/constants';
9
9
 
10
- function logTTExistanceWarning(log: ILogger, maybeTT: string, method: string) {
10
+ function logTTExistenceWarning(log: ILogger, maybeTT: string, method: string) {
11
11
  log.warn(WARN_NOT_EXISTENT_TT, [method, maybeTT]);
12
12
  }
13
13
 
14
14
  /**
15
15
  * Separated from the previous method since on some cases it'll be async.
16
16
  */
17
- export function validateTrafficTypeExistance(log: ILogger, readinessManager: IReadinessManager, splitsCache: ISplitsCacheBase, mode: SDKMode, maybeTT: string, method: string): MaybeThenable<boolean> {
17
+ export function validateTrafficTypeExistence(log: ILogger, readinessManager: IReadinessManager, splitsCache: ISplitsCacheBase, mode: SDKMode, maybeTT: string, method: string): MaybeThenable<boolean> {
18
18
 
19
19
  // If not ready or in localhost mode, we won't run the validation
20
20
  if (!readinessManager.isReady() || mode === LOCALHOST_MODE) return true;
@@ -23,11 +23,11 @@ export function validateTrafficTypeExistance(log: ILogger, readinessManager: IRe
23
23
 
24
24
  if (thenable(res)) {
25
25
  return res.then(function (isValid) {
26
- if (!isValid) logTTExistanceWarning(log, maybeTT, method);
26
+ if (!isValid) logTTExistenceWarning(log, maybeTT, method);
27
27
  return isValid; // propagate result
28
28
  });
29
29
  } else {
30
- if (!res) logTTExistanceWarning(log, maybeTT, method);
30
+ if (!res) logTTExistenceWarning(log, maybeTT, method);
31
31
  return res;
32
32
  }
33
33
  }
@@ -26,8 +26,6 @@ export class RedisMock {
26
26
  this.pipelineMethods[method] = this[method];
27
27
  });
28
28
 
29
- this.pipeline = jest.fn(() => {return this.pipelineMethods;});
29
+ this.pipeline = jest.fn(() => { return this.pipelineMethods; });
30
30
  }
31
-
32
-
33
31
  }
@@ -1,9 +1,9 @@
1
1
  import { IIntegrationManager, IIntegrationFactoryParams } from '../integrations/types';
2
2
  import { ISignalListener } from '../listeners/types';
3
- import { ILogger } from '../logger/types';
4
3
  import { IReadinessManager, ISdkReadinessManager } from '../readiness/types';
4
+ import type { sdkManagerFactory } from '../sdkManager';
5
5
  import { IFetch, ISplitApi, IEventSourceConstructor } from '../services/types';
6
- import { IStorageAsync, IStorageSync, ISplitsCacheSync, ISplitsCacheAsync, IStorageFactoryParams } from '../storages/types';
6
+ import { IStorageAsync, IStorageSync, IStorageFactoryParams } from '../storages/types';
7
7
  import { ISyncManager } from '../sync/types';
8
8
  import { IImpressionObserver } from '../trackers/impressionObserver/types';
9
9
  import { IImpressionsTracker, IEventTracker, ITelemetryTracker, IFilterAdapter, IUniqueKeysTracker } from '../trackers/types';
@@ -66,7 +66,7 @@ export interface ISdkFactoryParams {
66
66
  storageFactory: (params: IStorageFactoryParams) => IStorageSync | IStorageAsync;
67
67
  splitApiFactory?: (settings: ISettings, platform: IPlatform, telemetryTracker: ITelemetryTracker) => ISplitApi;
68
68
  syncManagerFactory?: (params: ISdkFactoryContextSync) => ISyncManager;
69
- sdkManagerFactory: (log: ILogger, splits: ISplitsCacheSync | ISplitsCacheAsync, sdkReadinessManager: ISdkReadinessManager) => SplitIO.IManager | SplitIO.IAsyncManager;
69
+ sdkManagerFactory: typeof sdkManagerFactory;
70
70
  sdkClientMethodFactory: (params: ISdkFactoryContext) => ({
71
71
  (): SplitIO.ICsClient;
72
72
  (key: SplitIO.SplitKey, trafficType?: string | undefined): SplitIO.ICsClient;
@@ -1,5 +1,4 @@
1
1
  import { ISplitsCacheAsync, ISplitsCacheSync } from '../storages/types';
2
2
  import { ISdkReadinessManager } from '../readiness/types';
3
- import { SplitIO } from '../types';
4
- import { ILogger } from '../logger/types';
5
- export declare function sdkManagerFactory<TSplitCache extends ISplitsCacheSync | ISplitsCacheAsync>(log: ILogger, splits: TSplitCache, { readinessManager, sdkStatus }: ISdkReadinessManager): TSplitCache extends ISplitsCacheAsync ? SplitIO.IAsyncManager : SplitIO.IManager;
3
+ import { ISettings, SplitIO } from '../types';
4
+ export declare function sdkManagerFactory<TSplitCache extends ISplitsCacheSync | ISplitsCacheAsync>(settings: Pick<ISettings, 'log' | 'mode'>, splits: TSplitCache, { readinessManager, sdkStatus }: ISdkReadinessManager): TSplitCache extends ISplitsCacheAsync ? SplitIO.IAsyncManager : SplitIO.IManager;
@@ -1,15 +1,15 @@
1
1
  import { IEventsCacheAsync } from '../types';
2
2
  import { IMetadata } from '../../dtos/types';
3
- import { Redis } from 'ioredis';
4
3
  import { SplitIO } from '../../types';
5
4
  import { ILogger } from '../../logger/types';
6
5
  import { StoredEventWithMetadata } from '../../sync/submitters/types';
6
+ import type { RedisAdapter } from './RedisAdapter';
7
7
  export declare class EventsCacheInRedis implements IEventsCacheAsync {
8
8
  private readonly log;
9
9
  private readonly key;
10
10
  private readonly redis;
11
11
  private readonly metadata;
12
- constructor(log: ILogger, key: string, redis: Redis, metadata: IMetadata);
12
+ constructor(log: ILogger, key: string, redis: RedisAdapter, metadata: IMetadata);
13
13
  /**
14
14
  * Add a new event object into the queue.
15
15
  * Unlike `impressions::track`, result promise is never rejected.
@@ -1,14 +1,15 @@
1
- import { Redis } from 'ioredis';
1
+ /// <reference types="ioredis" />
2
2
  import { ILogger } from '../../logger/types';
3
3
  import { ImpressionCountsPayload } from '../../sync/submitters/types';
4
4
  import { ImpressionCountsCacheInMemory } from '../inMemory/ImpressionCountsCacheInMemory';
5
+ import type { RedisAdapter } from './RedisAdapter';
5
6
  export declare class ImpressionCountsCacheInRedis extends ImpressionCountsCacheInMemory {
6
7
  private readonly log;
7
8
  private readonly key;
8
9
  private readonly redis;
9
10
  private readonly refreshRate;
10
11
  private intervalId;
11
- constructor(log: ILogger, key: string, redis: Redis, impressionCountsCacheSize?: number, refreshRate?: number);
12
+ constructor(log: ILogger, key: string, redis: RedisAdapter, impressionCountsCacheSize?: number, refreshRate?: number);
12
13
  private postImpressionCountsInRedis;
13
14
  start(): void;
14
15
  stop(): Promise<boolean | import("ioredis").BooleanResponse | undefined>;
@@ -1,15 +1,15 @@
1
1
  import { IImpressionsCacheAsync } from '../types';
2
2
  import { IMetadata } from '../../dtos/types';
3
3
  import { ImpressionDTO } from '../../types';
4
- import { Redis } from 'ioredis';
5
4
  import { StoredImpressionWithMetadata } from '../../sync/submitters/types';
6
5
  import { ILogger } from '../../logger/types';
6
+ import type { RedisAdapter } from './RedisAdapter';
7
7
  export declare class ImpressionsCacheInRedis implements IImpressionsCacheAsync {
8
8
  private readonly log;
9
9
  private readonly key;
10
10
  private readonly redis;
11
11
  private readonly metadata;
12
- constructor(log: ILogger, key: string, redis: Redis, metadata: IMetadata);
12
+ constructor(log: ILogger, key: string, redis: RedisAdapter, metadata: IMetadata);
13
13
  track(impressions: ImpressionDTO[]): Promise<void>;
14
14
  count(): Promise<number>;
15
15
  drop(count?: number): Promise<any>;
@@ -8,7 +8,7 @@ export declare class RedisAdapter extends ioredis {
8
8
  private _options;
9
9
  private _notReadyCommandsQueue?;
10
10
  private _runningCommands;
11
- constructor(log: ILogger, storageSettings: Record<string, any>);
11
+ constructor(log: ILogger, storageSettings?: Record<string, any>);
12
12
  _listenToEvents(): void;
13
13
  _setTimeoutWrappers(): void;
14
14
  _setDisconnectWrapper(): void;
@@ -1,12 +1,12 @@
1
- import { Redis } from 'ioredis';
2
1
  import { ILogger } from '../../logger/types';
3
2
  import { KeyBuilderSS } from '../KeyBuilderSS';
4
3
  import { ISegmentsCacheAsync } from '../types';
4
+ import type { RedisAdapter } from './RedisAdapter';
5
5
  export declare class SegmentsCacheInRedis implements ISegmentsCacheAsync {
6
6
  private readonly log;
7
7
  private readonly redis;
8
8
  private readonly keys;
9
- constructor(log: ILogger, keys: KeyBuilderSS, redis: Redis);
9
+ constructor(log: ILogger, keys: KeyBuilderSS, redis: RedisAdapter);
10
10
  addToSegment(name: string, segmentKeys: string[]): Promise<boolean>;
11
11
  removeFromSegment(name: string, segmentKeys: string[]): Promise<boolean>;
12
12
  isInSegment(name: string, key: string): Promise<boolean>;
@@ -14,5 +14,5 @@ export declare class SegmentsCacheInRedis implements ISegmentsCacheAsync {
14
14
  getChangeNumber(name: string): Promise<number>;
15
15
  registerSegments(segments: string[]): Promise<boolean>;
16
16
  getRegisteredSegments(): Promise<string[]>;
17
- clear(): Promise<boolean>;
17
+ clear(): Promise<void>;
18
18
  }
@@ -1,9 +1,9 @@
1
1
  import { KeyBuilderSS } from '../KeyBuilderSS';
2
- import { Redis } from 'ioredis';
3
2
  import { ILogger } from '../../logger/types';
4
3
  import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
5
4
  import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
6
5
  import { ISet } from '../../utils/lang/sets';
6
+ import type { RedisAdapter } from './RedisAdapter';
7
7
  /**
8
8
  * ISplitsCacheAsync implementation that stores split definitions in Redis.
9
9
  * Supported by Node.
@@ -14,7 +14,7 @@ export declare class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
14
14
  private readonly keys;
15
15
  private redisError?;
16
16
  private readonly flagSetsFilter;
17
- constructor(log: ILogger, keys: KeyBuilderSS, redis: Redis, splitFiltersValidation?: ISplitFiltersValidation);
17
+ constructor(log: ILogger, keys: KeyBuilderSS, redis: RedisAdapter, splitFiltersValidation?: ISplitFiltersValidation);
18
18
  private _decrementCounts;
19
19
  private _incrementCounts;
20
20
  private _updateFlagSets;
@@ -75,9 +75,9 @@ export declare class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
75
75
  */
76
76
  getSplitNames(): Promise<string[]>;
77
77
  /**
78
- * Get list of split names related to a given flag set names list.
79
- * The returned promise is resolved with the list of split names,
80
- * or rejected if any wrapper operation fails.
78
+ * Get list of feature flag names related to a given list of flag set names.
79
+ * The returned promise is resolved with the list of feature flag names per flag set,
80
+ * or rejected if the pipelined redis operation fails (e.g., timeout).
81
81
  */
82
82
  getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>[]>;
83
83
  /**
@@ -87,12 +87,7 @@ export declare class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
87
87
  * It will never be rejected.
88
88
  */
89
89
  trafficTypeExists(trafficType: string): Promise<boolean>;
90
- /**
91
- * Delete everything in the current database.
92
- *
93
- * @NOTE documentation says it never fails.
94
- */
95
- clear(): Promise<boolean>;
90
+ clear(): Promise<void>;
96
91
  /**
97
92
  * Fetches multiple splits definitions.
98
93
  * Returned promise is rejected if redis operation fails.
@@ -2,7 +2,7 @@ import { ILogger } from '../../logger/types';
2
2
  import { Method, MultiConfigs, MultiMethodExceptions, MultiMethodLatencies } from '../../sync/submitters/types';
3
3
  import { KeyBuilderSS } from '../KeyBuilderSS';
4
4
  import { ITelemetryCacheAsync } from '../types';
5
- import { Redis } from 'ioredis';
5
+ import type { RedisAdapter } from './RedisAdapter';
6
6
  export declare class TelemetryCacheInRedis implements ITelemetryCacheAsync {
7
7
  private readonly log;
8
8
  private readonly keys;
@@ -13,7 +13,7 @@ export declare class TelemetryCacheInRedis implements ITelemetryCacheAsync {
13
13
  * @param keys Key builder.
14
14
  * @param redis Redis client.
15
15
  */
16
- constructor(log: ILogger, keys: KeyBuilderSS, redis: Redis);
16
+ constructor(log: ILogger, keys: KeyBuilderSS, redis: RedisAdapter);
17
17
  recordLatency(method: Method, latencyMs: number): Promise<number | void>;
18
18
  recordException(method: Method): Promise<number | void>;
19
19
  recordConfig(): Promise<number | void>;
@@ -1,15 +1,16 @@
1
+ /// <reference types="ioredis" />
1
2
  import { IUniqueKeysCacheBase } from '../types';
2
- import { Redis } from 'ioredis';
3
3
  import { UniqueKeysCacheInMemory } from '../inMemory/UniqueKeysCacheInMemory';
4
4
  import { ILogger } from '../../logger/types';
5
5
  import { UniqueKeysItemSs } from '../../sync/submitters/types';
6
+ import type { RedisAdapter } from './RedisAdapter';
6
7
  export declare class UniqueKeysCacheInRedis extends UniqueKeysCacheInMemory implements IUniqueKeysCacheBase {
7
8
  private readonly log;
8
9
  private readonly key;
9
10
  private readonly redis;
10
11
  private readonly refreshRate;
11
12
  private intervalId;
12
- constructor(log: ILogger, key: string, redis: Redis, uniqueKeysQueueSize?: number, refreshRate?: number);
13
+ constructor(log: ILogger, key: string, redis: RedisAdapter, uniqueKeysQueueSize?: number, refreshRate?: number);
13
14
  private postUniqueKeysInRedis;
14
15
  start(): void;
15
16
  stop(): Promise<boolean | import("ioredis").BooleanResponse | undefined>;
@@ -71,10 +71,10 @@ export declare class SplitsCachePluggable extends AbstractSplitsCacheAsync {
71
71
  */
72
72
  getSplitNames(): Promise<string[]>;
73
73
  /**
74
- * Get list of split names related to a given flag set names list.
75
- * The returned promise is resolved with the list of split names,
76
- * or rejected if any wrapper operation fails.
77
- */
74
+ * Get list of feature flag names related to a given list of flag set names.
75
+ * The returned promise is resolved with the list of feature flag names per flag set.
76
+ * It never rejects (If there is a wrapper error for some flag set, an empty set is returned for it).
77
+ */
78
78
  getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>[]>;
79
79
  /**
80
80
  * Check traffic type existence.
@@ -2,4 +2,4 @@ import { ISettings } from '../../types';
2
2
  /**
3
3
  * Storage is async if mode is consumer or partial consumer
4
4
  */
5
- export declare function isStorageSync(settings: ISettings): boolean;
5
+ export declare function isStorageSync(settings: Pick<ISettings, 'mode'>): boolean;
@@ -8,6 +8,6 @@ export { validateSplit } from './split';
8
8
  export { validateSplits } from './splits';
9
9
  export { validateTrafficType } from './trafficType';
10
10
  export { validateIfNotDestroyed, validateIfOperational } from './isOperational';
11
- export { validateSplitExistance } from './splitExistance';
12
- export { validateTrafficTypeExistance } from './trafficTypeExistance';
11
+ export { validateSplitExistence } from './splitExistence';
12
+ export { validateTrafficTypeExistence } from './trafficTypeExistence';
13
13
  export { validatePreloadedData } from './preloadedData';
@@ -0,0 +1,7 @@
1
+ import { IReadinessManager } from '../../readiness/types';
2
+ import { ILogger } from '../../logger/types';
3
+ /**
4
+ * This is defined here and in this format mostly because of the logger and the fact that it's considered a validation at product level.
5
+ * But it's not going to run on the input validation layer. In any case, the most compeling reason to use it as we do is to avoid going to Redis and get a split twice.
6
+ */
7
+ export declare function validateSplitExistence(log: ILogger, readinessManager: IReadinessManager, splitName: string, labelOrSplitObj: any, method: string): boolean;
@@ -0,0 +1,9 @@
1
+ import { ISplitsCacheBase } from '../../storages/types';
2
+ import { IReadinessManager } from '../../readiness/types';
3
+ import { SDKMode } from '../../types';
4
+ import { MaybeThenable } from '../../dtos/types';
5
+ import { ILogger } from '../../logger/types';
6
+ /**
7
+ * Separated from the previous method since on some cases it'll be async.
8
+ */
9
+ export declare function validateTrafficTypeExistence(log: ILogger, readinessManager: IReadinessManager, splitsCache: ISplitsCacheBase, mode: SDKMode, maybeTT: string, method: string): MaybeThenable<boolean>;