Skip to content

Commit 1d4d290

Browse files
authored
[FSSDK-11395] add specific type for decision notification (#1025)
1 parent eb40675 commit 1d4d290

File tree

8 files changed

+92
-33
lines changed

8 files changed

+92
-33
lines changed

Diff for: lib/common_exports.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ export { createErrorNotifier } from './error/error_notifier_factory';
3030

3131
export {
3232
DECISION_SOURCES,
33-
DECISION_NOTIFICATION_TYPES,
34-
NOTIFICATION_TYPES,
3533
} from './utils/enums';
3634

35+
export { NOTIFICATION_TYPES, DECISION_NOTIFICATION_TYPES } from './notification_center/type';
36+
3737
export { OptimizelyDecideOption } from './shared_types';

Diff for: lib/core/decision_service/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
AUDIENCE_EVALUATION_TYPES,
2020
CONTROL_ATTRIBUTES,
2121
DECISION_SOURCES,
22+
DecisionSource,
2223
} from '../../utils/enums';
2324
import {
2425
getAudiencesById,
@@ -114,7 +115,7 @@ export const CMAB_FETCHED_VARIATION_INVALID = 'Fetched variation %s for cmab exp
114115
export interface DecisionObj {
115116
experiment: Experiment | null;
116117
variation: Variation | null;
117-
decisionSource: string;
118+
decisionSource: DecisionSource;
118119
cmabUuid?: string;
119120
}
120121

Diff for: lib/entrypoint.test-d.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ import {
4848

4949
import {
5050
DECISION_SOURCES,
51-
DECISION_NOTIFICATION_TYPES,
52-
NOTIFICATION_TYPES,
5351
} from './utils/enums';
5452

53+
import { NOTIFICATION_TYPES, DECISION_NOTIFICATION_TYPES } from './notification_center/type';
54+
5555
import { LogLevel } from './logging/logger';
5656

5757
import { OptimizelyDecideOption } from './shared_types';
@@ -89,8 +89,8 @@ export type Entrypoint = {
8989

9090
// enums
9191
DECISION_SOURCES: typeof DECISION_SOURCES;
92-
DECISION_NOTIFICATION_TYPES: typeof DECISION_NOTIFICATION_TYPES;
9392
NOTIFICATION_TYPES: typeof NOTIFICATION_TYPES;
93+
DECISION_NOTIFICATION_TYPES: typeof DECISION_NOTIFICATION_TYPES;
9494

9595
// decide options
9696
OptimizelyDecideOption: typeof OptimizelyDecideOption;

Diff for: lib/entrypoint.universal.test-d.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ import { RequestHandler } from './utils/http_request_handler/http';
4141
import { UniversalBatchEventProcessorOptions } from './event_processor/event_processor_factory.universal';
4242
import {
4343
DECISION_SOURCES,
44-
DECISION_NOTIFICATION_TYPES,
45-
NOTIFICATION_TYPES,
4644
} from './utils/enums';
4745

46+
import { NOTIFICATION_TYPES, DECISION_NOTIFICATION_TYPES } from './notification_center/type';
47+
4848
import { LogLevel } from './logging/logger';
4949

5050
import { OptimizelyDecideOption } from './shared_types';
@@ -82,8 +82,8 @@ export type UniversalEntrypoint = {
8282

8383
// enums
8484
DECISION_SOURCES: typeof DECISION_SOURCES;
85-
DECISION_NOTIFICATION_TYPES: typeof DECISION_NOTIFICATION_TYPES;
8685
NOTIFICATION_TYPES: typeof NOTIFICATION_TYPES;
86+
DECISION_NOTIFICATION_TYPES: typeof DECISION_NOTIFICATION_TYPES;
8787

8888
// decide options
8989
OptimizelyDecideOption: typeof OptimizelyDecideOption;

Diff for: lib/notification_center/type.ts

+68-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2024, Optimizely
2+
* Copyright 2024-2025, Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,7 +15,9 @@
1515
*/
1616

1717
import { LogEvent } from '../event_processor/event_dispatcher/event_dispatcher';
18-
import { EventTags, Experiment, UserAttributes, Variation } from '../shared_types';
18+
import { EventTags, Experiment, FeatureVariableValue, UserAttributes, VariableType, Variation } from '../shared_types';
19+
import { DecisionSource } from '../utils/enums';
20+
import { Nullable } from '../utils/type';
1921

2022
export type UserEventListenerPayload = {
2123
userId: string;
@@ -43,16 +45,75 @@ export const DECISION_NOTIFICATION_TYPES = {
4345
FLAG: 'flag',
4446
} as const;
4547

48+
4649
export type DecisionNotificationType = typeof DECISION_NOTIFICATION_TYPES[keyof typeof DECISION_NOTIFICATION_TYPES];
4750

48-
// TODO: Add more specific types for decision info
49-
export type OptimizelyDecisionInfo = Record<string, any>;
51+
export type ExperimentAndVariationInfo = {
52+
experimentKey: string;
53+
variationKey: string;
54+
}
55+
56+
export type DecisionSourceInfo = Partial<ExperimentAndVariationInfo>;
5057

51-
export type DecisionListenerPayload = UserEventListenerPayload & {
52-
type: DecisionNotificationType;
53-
decisionInfo: OptimizelyDecisionInfo;
58+
export type AbTestDecisonInfo = Nullable<ExperimentAndVariationInfo, 'variationKey'>;
59+
60+
type FeatureDecisionInfo = {
61+
featureKey: string,
62+
featureEnabled: boolean,
63+
source: DecisionSource,
64+
sourceInfo: DecisionSourceInfo,
5465
}
5566

67+
export type FeatureTestDecisionInfo = Nullable<ExperimentAndVariationInfo, 'variationKey'>;
68+
69+
export type FeatureVariableDecisionInfo = {
70+
featureKey: string,
71+
featureEnabled: boolean,
72+
source: DecisionSource,
73+
variableKey: string,
74+
variableValue: FeatureVariableValue,
75+
variableType: VariableType,
76+
sourceInfo: DecisionSourceInfo,
77+
};
78+
79+
export type VariablesMap = { [variableKey: string]: unknown }
80+
81+
export type AllFeatureVariablesDecisionInfo = {
82+
featureKey: string,
83+
featureEnabled: boolean,
84+
source: DecisionSource,
85+
variableValues: VariablesMap,
86+
sourceInfo: DecisionSourceInfo,
87+
};
88+
89+
export type FlagDecisionInfo = {
90+
flagKey: string,
91+
enabled: boolean,
92+
variationKey: string | null,
93+
ruleKey: string | null,
94+
variables: VariablesMap,
95+
reasons: string[],
96+
decisionEventDispatched: boolean,
97+
};
98+
99+
export type DecisionInfo = {
100+
[DECISION_NOTIFICATION_TYPES.AB_TEST]: AbTestDecisonInfo;
101+
[DECISION_NOTIFICATION_TYPES.FEATURE]: FeatureDecisionInfo;
102+
[DECISION_NOTIFICATION_TYPES.FEATURE_TEST]: FeatureTestDecisionInfo;
103+
[DECISION_NOTIFICATION_TYPES.FEATURE_VARIABLE]: FeatureVariableDecisionInfo;
104+
[DECISION_NOTIFICATION_TYPES.ALL_FEATURE_VARIABLES]: AllFeatureVariablesDecisionInfo;
105+
[DECISION_NOTIFICATION_TYPES.FLAG]: FlagDecisionInfo;
106+
}
107+
108+
export type DecisionListenerPayloadForType<T extends DecisionNotificationType> = UserEventListenerPayload & {
109+
type: T;
110+
decisionInfo: DecisionInfo[T];
111+
}
112+
113+
export type DecisionListenerPayload = {
114+
[T in DecisionNotificationType]: DecisionListenerPayloadForType<T>;
115+
}[DecisionNotificationType];
116+
56117
export type LogEventListenerPayload = LogEvent;
57118

58119
export type OptimizelyConfigUpdateListenerPayload = undefined;

Diff for: lib/tests/test_data.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2021, 2024 Optimizely
2+
* Copyright 2016-2021, 2024-2025 Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -3555,7 +3555,7 @@ export var getMutexFeatureTestsConfig = function() {
35553555
export var rolloutDecisionObj = {
35563556
experiment: null,
35573557
variation: null,
3558-
decisionSource: 'rollout',
3558+
decisionSource: 'rollout' as const,
35593559
};
35603560

35613561
export var featureTestDecisionObj = {
@@ -3611,7 +3611,7 @@ export var featureTestDecisionObj = {
36113611
variables: [],
36123612
variablesMap: {}
36133613
},
3614-
decisionSource: 'feature-test',
3614+
decisionSource: 'feature-test' as const,
36153615
};
36163616

36173617
var similarRuleKeyConfig = {

Diff for: lib/utils/enums/index.ts

+4-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2024, Optimizely
2+
* Copyright 2016-2025, Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -44,15 +44,6 @@ export const NODE_CLIENT_ENGINE = 'node-sdk';
4444
export const REACT_NATIVE_JS_CLIENT_ENGINE = 'react-native-js-sdk';
4545
export const CLIENT_VERSION = '5.3.4';
4646

47-
export const DECISION_NOTIFICATION_TYPES = {
48-
AB_TEST: 'ab-test',
49-
FEATURE: 'feature',
50-
FEATURE_TEST: 'feature-test',
51-
FEATURE_VARIABLE: 'feature-variable',
52-
ALL_FEATURE_VARIABLES: 'all-feature-variables',
53-
FLAG: 'flag',
54-
};
55-
5647
/*
5748
* Represents the source of a decision for feature management. When a feature
5849
* is accessed through isFeatureEnabled or getVariableValue APIs, the decision
@@ -63,7 +54,9 @@ export const DECISION_SOURCES = {
6354
FEATURE_TEST: 'feature-test',
6455
ROLLOUT: 'rollout',
6556
EXPERIMENT: 'experiment',
66-
};
57+
} as const;
58+
59+
export type DecisionSource = typeof DECISION_SOURCES[keyof typeof DECISION_SOURCES];
6760

6861
export const AUDIENCE_EVALUATION_TYPES = {
6962
RULE: 'rule',
@@ -104,8 +97,6 @@ export const DECISION_MESSAGES = {
10497
VARIABLE_VALUE_INVALID: 'Variable value for key "%s" is invalid or wrong type.',
10598
};
10699

107-
export { NOTIFICATION_TYPES } from '../../notification_center/type';
108-
109100
/**
110101
* Default milliseconds before request timeout
111102
*/

Diff for: lib/utils/type.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2024, Optimizely
2+
* Copyright 2024-2025, Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,3 +31,9 @@ export type Either<A, B> = { type: 'left', value: A } | { type: 'right', value:
3131

3232
export type OpType = 'sync' | 'async';
3333
export type OpValue<O extends OpType, V> = O extends 'sync' ? V : Promise<V>;
34+
35+
export type OrNull<T> = T | null;
36+
37+
export type Nullable<T, K extends keyof T> = {
38+
[P in keyof T]: P extends K ? OrNull<T[P]> : T[P];
39+
}

0 commit comments

Comments
 (0)