Skip to content

Commit 2ceb6ce

Browse files
committed
feat: renamed-and-moved-features-evaluation-to-engine
1 parent 5e039c0 commit 2ceb6ce

File tree

3 files changed

+35
-25
lines changed

3 files changed

+35
-25
lines changed

flagsmith-engine/features/util.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,3 @@ export function buildFeatureStateModel(featuresStateModelJSON: any): FeatureStat
4949
export function buildFeatureSegment(featureSegmentJSON: any): FeatureSegment {
5050
return new FeatureSegment(featureSegmentJSON.priority);
5151
}
52-
53-
export function evaluateFeatureValue(feature: FeatureContext, identityKey?: string): any {
54-
if (!!feature.variants && feature.variants.length > 0 && !!identityKey) {
55-
return evaluateMultivariateFeature(feature, identityKey);
56-
}
57-
58-
return feature.value;
59-
}
60-
61-
function evaluateMultivariateFeature(feature: FeatureContext, identityKey?: string): any {
62-
const percentageValue = getHashedPercentageForObjIds([feature.key, identityKey]);
63-
64-
let startPercentage = 0;
65-
for (const variant of feature?.variants || []) {
66-
const limit = startPercentage + variant.weight;
67-
68-
if (startPercentage <= percentageValue && percentageValue < limit) {
69-
return variant.value;
70-
}
71-
startPercentage = limit;
72-
}
73-
return feature.value;
74-
}

flagsmith-engine/index.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { EvaluationContext, FeatureContext } from './evaluation/models.js';
22
import { getIdentitySegments } from './segments/evaluators.js';
33
import { EvaluationResult, EvaluationResultFlags } from './evaluation/models.js';
4-
import { evaluateFeatureValue } from './features/util.js';
54
import { TARGETING_REASONS } from './features/types.js';
5+
import { getHashedPercentageForObjIds } from './utils/hashing/index.js';
66
export { EnvironmentModel } from './environments/models.js';
77
export { IdentityModel } from './identities/models.js';
88
export { TraitModel } from './identities/traits/models.js';
@@ -124,6 +124,39 @@ export function evaluateFeatures(
124124
return flags;
125125
}
126126

127+
function evaluateFeatureValue(feature: FeatureContext, identityKey?: string): any {
128+
if (!!feature.variants && feature.variants.length > 0 && !!identityKey) {
129+
return getMultivariateFeatureValue(feature, identityKey);
130+
}
131+
132+
return feature.value;
133+
}
134+
135+
/**
136+
* Evaluates a multivariate feature flag to determine which variant value to return for a given identity.
137+
*
138+
* Uses deterministic hashing to ensure the same identity always receives the same variant,
139+
* while distributing variants according to their configured weight percentages.
140+
*
141+
* @param feature - The feature context containing variants and their weights
142+
* @param identityKey - The identity key used for deterministic variant selection
143+
* @returns The variant value if the identity falls within a variant's range, otherwise the default feature value
144+
*/
145+
function getMultivariateFeatureValue(feature: FeatureContext, identityKey?: string): any {
146+
const percentageValue = getHashedPercentageForObjIds([feature.key, identityKey]);
147+
148+
let startPercentage = 0;
149+
for (const variant of feature?.variants || []) {
150+
const limit = startPercentage + variant.weight;
151+
152+
if (startPercentage <= percentageValue && percentageValue < limit) {
153+
return variant.value;
154+
}
155+
startPercentage = limit;
156+
}
157+
return feature.value;
158+
}
159+
127160
export function shouldApplyOverride(
128161
override: any,
129162
existingOverrides: Record<string, SegmentOverride>

0 commit comments

Comments
 (0)