diff --git a/src/evaluator/index.ts b/src/evaluator/index.ts index e465b9bf..9b7e2d70 100644 --- a/src/evaluator/index.ts +++ b/src/evaluator/index.ts @@ -30,6 +30,7 @@ export function evaluateFeature( splitName: string, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync, + options?: SplitIO.EvaluationOptions ): MaybeThenable { let parsedSplit; @@ -47,6 +48,7 @@ export function evaluateFeature( split, attributes, storage, + options, )).catch( // Exception on async `getSplit` storage. For example, when the storage is redis or // pluggable and there is a connection issue and we can't retrieve the split to be evaluated @@ -60,6 +62,7 @@ export function evaluateFeature( parsedSplit, attributes, storage, + options, ); } @@ -69,6 +72,7 @@ export function evaluateFeatures( splitNames: string[], attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync, + options?: SplitIO.EvaluationOptions, ): MaybeThenable> { let parsedSplits; @@ -80,13 +84,13 @@ export function evaluateFeatures( } return thenable(parsedSplits) ? - parsedSplits.then(splits => getEvaluations(log, key, splitNames, splits, attributes, storage)) + parsedSplits.then(splits => getEvaluations(log, key, splitNames, splits, attributes, storage, options)) .catch(() => { // Exception on async `getSplits` storage. For example, when the storage is redis or // pluggable and there is a connection issue and we can't retrieve the split to be evaluated return treatmentsException(splitNames); }) : - getEvaluations(log, key, splitNames, parsedSplits, attributes, storage); + getEvaluations(log, key, splitNames, parsedSplits, attributes, storage, options); } export function evaluateFeaturesByFlagSets( @@ -96,6 +100,7 @@ export function evaluateFeaturesByFlagSets( attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync, method: string, + options?: SplitIO.EvaluationOptions, ): MaybeThenable> { let storedFlagNames: MaybeThenable[]>; @@ -111,7 +116,7 @@ export function evaluateFeaturesByFlagSets( } return featureFlags.size ? - evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage) : + evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage, options) : {}; } @@ -138,6 +143,7 @@ function getEvaluation( splitJSON: ISplit | null, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync, + options?: SplitIO.EvaluationOptions, ): MaybeThenable { let evaluation: MaybeThenable = { treatment: CONTROL, @@ -154,14 +160,14 @@ function getEvaluation( return evaluation.then(result => { result.changeNumber = splitJSON.changeNumber; result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null; - result.impressionsDisabled = splitJSON.impressionsDisabled; + result.impressionsDisabled = options?.impressionsDisabled || splitJSON.impressionsDisabled; return result; }); } else { evaluation.changeNumber = splitJSON.changeNumber; evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null; - evaluation.impressionsDisabled = splitJSON.impressionsDisabled; + evaluation.impressionsDisabled = options?.impressionsDisabled || splitJSON.impressionsDisabled; } } @@ -175,6 +181,7 @@ function getEvaluations( splits: Record, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync, + options?: SplitIO.EvaluationOptions, ): MaybeThenable> { const result: Record = {}; const thenables: Promise[] = []; @@ -184,7 +191,8 @@ function getEvaluations( key, splits[splitName], attributes, - storage + storage, + options ); if (thenable(evaluation)) { thenables.push(evaluation.then(res => { diff --git a/src/sdkClient/client.ts b/src/sdkClient/client.ts index 0e526f72..a48e738c 100644 --- a/src/sdkClient/client.ts +++ b/src/sdkClient/client.ts @@ -52,7 +52,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl }; const evaluation = readinessManager.isReady() || readinessManager.isReadyFromCache() ? - evaluateFeature(log, key, featureFlagName, attributes, storage) : + evaluateFeature(log, key, featureFlagName, attributes, storage, options) : isAsync ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected Promise.resolve(treatmentNotReady) : treatmentNotReady; @@ -81,7 +81,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl }; const evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ? - evaluateFeatures(log, key, featureFlagNames, attributes, storage) : + evaluateFeatures(log, key, featureFlagNames, attributes, storage, options) : isAsync ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected Promise.resolve(treatmentsNotReady(featureFlagNames)) : treatmentsNotReady(featureFlagNames); @@ -110,7 +110,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl }; const evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ? - evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName) : + evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName, options) : isAsync ? Promise.resolve({}) : {}; diff --git a/types/splitio.d.ts b/types/splitio.d.ts index 4062e012..9e93d2eb 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -838,8 +838,16 @@ declare namespace SplitIO { * Evaluation options object for getTreatment methods. */ type EvaluationOptions = { + /** + * Whether the evaluation/s will track impressions or not. + * + * @defaultValue `false` + */ + impressionsDisabled?: boolean; /** * Optional properties to append to the generated impression object sent to Split backend. + * + * @defaultValue `undefined` */ properties?: Properties; }