Skip to content

Commit b992a20

Browse files
Merge pull request #480 from splitio/refactor-fallback-calculator
General polishing: fix mocks, simplify fallback calculator, remove redundant logs, etc
2 parents 5121dd8 + cc3f145 commit b992a20

File tree

16 files changed

+132
-177
lines changed

16 files changed

+132
-177
lines changed

CHANGES.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
2.12.0 (February 24, 2026)
2-
- Added support for ioredis v5.
2+
- Added support for ioredis v5 (Related to issue https://github.com/splitio/javascript-commons/issues/471).
33

44
2.11.0 (January 28, 2026)
55
- Added functionality to provide metadata alongside SDK update and READY events. Read more in our docs.

src/dtos/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export interface IBetweenStringMatcherData {
2323
}
2424

2525
export interface IWhitelistMatcherData {
26-
whitelist: string[]
26+
whitelist?: string[] | null
2727
}
2828

2929
export interface IInSegmentMatcherData {

src/evaluator/__tests__/evaluate-feature.spec.ts

Lines changed: 24 additions & 23 deletions
Large diffs are not rendered by default.

src/evaluator/__tests__/evaluate-features.spec.ts

Lines changed: 26 additions & 27 deletions
Large diffs are not rendered by default.

src/evaluator/condition/engineUtils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ export function getTreatment(log: ILogger, key: string, seed: number | undefined
1818
/**
1919
* Evaluates the traffic allocation to see if we should apply rollout conditions or not.
2020
*/
21-
export function shouldApplyRollout(trafficAllocation: number, key: string, trafficAllocationSeed: number) {
21+
export function shouldApplyRollout(trafficAllocation: number, bucketingKey: string, trafficAllocationSeed: number) {
2222
// For rollout, if traffic allocation for splits is 100%, we don't need to filter it because everything should evaluate the rollout.
2323
if (trafficAllocation < 100) {
24-
const _bucket = bucket(key, trafficAllocationSeed);
24+
const _bucket = bucket(bucketingKey, trafficAllocationSeed);
2525

2626
if (_bucket > trafficAllocation) {
2727
return false;

src/evaluator/fallbackTreatmentsCalculator/__tests__/fallback-calculator.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ describe('FallbackTreatmentsCalculator' , () => {
99
'featureA': { treatment: 'TREATMENT_A', config: '{ value: 1 }' },
1010
},
1111
};
12-
const calculator = new FallbackTreatmentsCalculator(config);
13-
const result = calculator.resolve('featureA', 'label by flag');
12+
const calculator = FallbackTreatmentsCalculator(config);
13+
const result = calculator('featureA', 'label by flag');
1414

1515
expect(result).toEqual({
1616
treatment: 'TREATMENT_A',
@@ -24,8 +24,8 @@ describe('FallbackTreatmentsCalculator' , () => {
2424
byFlag: {},
2525
global: { treatment: 'GLOBAL_TREATMENT', config: '{ global: true }' },
2626
};
27-
const calculator = new FallbackTreatmentsCalculator(config);
28-
const result = calculator.resolve('missingFlag', 'label by global');
27+
const calculator = FallbackTreatmentsCalculator(config);
28+
const result = calculator('missingFlag', 'label by global');
2929

3030
expect(result).toEqual({
3131
treatment: 'GLOBAL_TREATMENT',
@@ -38,8 +38,8 @@ describe('FallbackTreatmentsCalculator' , () => {
3838
const config: FallbackTreatmentConfiguration = {
3939
byFlag: {},
4040
};
41-
const calculator = new FallbackTreatmentsCalculator(config);
42-
const result = calculator.resolve('missingFlag', 'label by noFallback');
41+
const calculator = FallbackTreatmentsCalculator(config);
42+
const result = calculator('missingFlag', 'label by noFallback');
4343

4444
expect(result).toEqual({
4545
treatment: CONTROL,
Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,32 @@
1-
import { FallbackTreatmentConfiguration, Treatment, TreatmentWithConfig } from '../../../types/splitio';
1+
import { FallbackTreatmentConfiguration, TreatmentWithConfig } from '../../../types/splitio';
22
import { CONTROL } from '../../utils/constants';
33
import { isString } from '../../utils/lang';
44

5-
export type IFallbackTreatmentsCalculator = {
6-
resolve(flagName: string, label: string): TreatmentWithConfig & { label: string };
7-
}
5+
export type IFallbackTreatmentsCalculator = (flagName: string, label?: string) => TreatmentWithConfig & { label: string };
86

97
export const FALLBACK_PREFIX = 'fallback - ';
108

11-
export class FallbackTreatmentsCalculator implements IFallbackTreatmentsCalculator {
12-
private readonly fallbacks: FallbackTreatmentConfiguration;
13-
14-
constructor(fallbacks: FallbackTreatmentConfiguration = {}) {
15-
this.fallbacks = fallbacks;
16-
}
17-
18-
resolve(flagName: string, label: string): TreatmentWithConfig & { label: string } {
19-
const treatment = this.fallbacks.byFlag?.[flagName];
20-
if (treatment) {
21-
return this.copyWithLabel(treatment, label);
22-
}
23-
24-
if (this.fallbacks.global) {
25-
return this.copyWithLabel(this.fallbacks.global, label);
26-
}
27-
28-
return {
29-
treatment: CONTROL,
30-
config: null,
31-
label,
32-
};
33-
}
34-
35-
private copyWithLabel(fallback: Treatment | TreatmentWithConfig, label: string): TreatmentWithConfig & { label: string } {
36-
if (isString(fallback)) {
37-
return {
38-
treatment: fallback,
9+
export function FallbackTreatmentsCalculator(fallbacks: FallbackTreatmentConfiguration = {}): IFallbackTreatmentsCalculator {
10+
11+
return (flagName: string, label = '') => {
12+
const fallback = fallbacks.byFlag?.[flagName] || fallbacks.global;
13+
14+
return fallback ?
15+
isString(fallback) ?
16+
{
17+
treatment: fallback,
18+
config: null,
19+
label: `${FALLBACK_PREFIX}${label}`,
20+
} :
21+
{
22+
treatment: fallback.treatment,
23+
config: fallback.config,
24+
label: `${FALLBACK_PREFIX}${label}`,
25+
} :
26+
{
27+
treatment: CONTROL,
3928
config: null,
40-
label: `${FALLBACK_PREFIX}${label}`,
29+
label,
4130
};
42-
}
43-
44-
return {
45-
treatment: fallback.treatment,
46-
config: fallback.config,
47-
label: `${FALLBACK_PREFIX}${label}`,
48-
};
49-
}
31+
};
5032
}

src/evaluator/matchers/whitelist.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
export function whitelistMatcherContext(ruleAttr: string[]) {
2-
const whitelistSet = new Set(ruleAttr);
1+
export function whitelistMatcherContext(ruleAttr?: string[] | null) {
2+
const whitelistSet = new Set(ruleAttr || []);
33

44
return function whitelistMatcher(runtimeAttr: string): boolean {
55
const isInWhitelist = whitelistSet.has(runtimeAttr);

src/logger/constants.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ export const ENGINE_DEFAULT = 41;
3232

3333
export const CLIENT_READY_FROM_CACHE = 100;
3434
export const CLIENT_READY = 101;
35-
export const IMPRESSION = 102;
3635
export const IMPRESSION_QUEUEING = 103;
3736
export const NEW_SHARED_CLIENT = 104;
3837
export const NEW_FACTORY = 105;

src/logger/messages/info.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ export const codesInfo: [number, string][] = codesWarn.concat([
88
[c.CLIENT_READY_FROM_CACHE, READY_MSG + ' from cache'],
99
[c.CLIENT_READY, READY_MSG],
1010
// SDK
11-
[c.IMPRESSION, c.LOG_PREFIX_IMPRESSIONS_TRACKER +'Feature flag: %s. Key: %s. Evaluation: %s. Label: %s'],
12-
[c.IMPRESSION_QUEUEING, c.LOG_PREFIX_IMPRESSIONS_TRACKER +'Queueing corresponding impression.'],
11+
[c.IMPRESSION_QUEUEING, c.LOG_PREFIX_IMPRESSIONS_TRACKER +'Queueing impression. Feature flag: %s. Key: %s. Evaluation: %s. Label: %s'],
1312
[c.NEW_SHARED_CLIENT, 'New shared client instance created.'],
1413
[c.NEW_FACTORY, 'New Split SDK instance created. %s'],
1514
[c.EVENTS_TRACKER_SUCCESS, c.LOG_PREFIX_EVENTS_TRACKER + 'Successfully queued %s'],

0 commit comments

Comments
 (0)