Skip to content

Commit 8b80447

Browse files
[FSSDK-12115] type def update
1 parent ae2b895 commit 8b80447

File tree

5 files changed

+130
-19
lines changed

5 files changed

+130
-19
lines changed

lib/core/decision_service/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import * as stringValidator from '../../utils/string_value_validator';
4444
import {
4545
BucketerParams,
4646
DecisionResponse,
47+
DecisionSource,
4748
Experiment,
4849
ExperimentBucketMap,
4950
FeatureFlag,
@@ -60,7 +61,7 @@ const MODULE_NAME = 'DECISION_SERVICE';
6061
export interface DecisionObj {
6162
experiment: Experiment | null;
6263
variation: Variation | null;
63-
decisionSource: string;
64+
decisionSource: DecisionSource;
6465
}
6566

6667
interface DecisionServiceOptions {

lib/core/notification_center/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
import { LogHandler, ErrorHandler } from '../../modules/logging';
1717
import { objectValues } from '../../utils/fns';
18-
import { NotificationListener, ListenerPayload } from '../../shared_types';
18+
import { NotificationListener, NotificationPayloadMap } from '../../shared_types';
1919

2020
import {
2121
LOG_LEVEL,
@@ -80,9 +80,9 @@ export class NotificationCenter {
8080
* can happen if the first argument is not a valid notification type, or if the same callback
8181
* function was already added as a listener by a prior call to this function.
8282
*/
83-
addNotificationListener<T extends ListenerPayload>(
84-
notificationType: string,
85-
callback: NotificationListener<T>
83+
addNotificationListener<K extends keyof NotificationPayloadMap>(
84+
notificationType: K,
85+
callback: NotificationListener<NotificationPayloadMap[K]>
8686
): number {
8787
try {
8888
const notificationTypeValues: string[] = objectValues(NOTIFICATION_TYPES);
@@ -202,9 +202,9 @@ export class NotificationCenter {
202202
* @param {string} notificationType One of NOTIFICATION_TYPES
203203
* @param {Object} notificationData Will be passed to callbacks called
204204
*/
205-
sendNotifications<T extends ListenerPayload>(
206-
notificationType: string,
207-
notificationData?: T
205+
sendNotifications<K extends keyof NotificationPayloadMap>(
206+
notificationType: K,
207+
notificationData?: NotificationPayloadMap[K]
208208
): void {
209209
try {
210210
(this.notificationListeners[notificationType] || []).forEach(

lib/export_types.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ export {
3737
UserProfileService,
3838
UserProfile,
3939
ListenerPayload,
40+
DecisionListenerPayload,
41+
LogEventListenerPayload,
42+
NotificationPayloadMap,
4043
OptimizelyDecision,
4144
OptimizelyUserContext,
4245
NotificationListener,
@@ -47,4 +50,18 @@ export {
4750
NotificationCenter,
4851
OptimizelySegmentOption,
4952
ICache,
53+
// Decision info types
54+
DecisionNotificationType,
55+
DecisionSource,
56+
DecisionSourceInfo,
57+
VariablesMap,
58+
// Specific decision info types for type narrowing
59+
AbTestDecisionInfo,
60+
FeatureDecisionInfo,
61+
FeatureTestDecisionInfo,
62+
FeatureVariableDecisionInfo,
63+
AllFeatureVariablesDecisionInfo,
64+
FlagDecisionInfo,
65+
DecisionInfoMap,
66+
DecisionListenerPayloadForType,
5067
} from './shared_types';

lib/shared_types.ts

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { ErrorHandler, LogHandler, LogLevel, LoggerFacade } from './modules/logg
2323
import { EventProcessor } from './modules/event_processor';
2424

2525
import { NotificationCenter as NotificationCenterImpl } from './core/notification_center';
26-
import { NOTIFICATION_TYPES } from './utils/enums';
26+
import { NOTIFICATION_TYPES, DECISION_NOTIFICATION_TYPES, DECISION_SOURCES } from './utils/enums';
2727

2828
import { IOptimizelyUserContext as OptimizelyUserContext } from './optimizely_user_context';
2929

@@ -120,13 +120,106 @@ export interface ListenerPayload {
120120
attributes?: UserAttributes;
121121
}
122122

123-
export type NotificationListener<T extends ListenerPayload> = (notificationData: T) => void;
123+
export type DecisionNotificationType =
124+
| typeof DECISION_NOTIFICATION_TYPES.AB_TEST
125+
| typeof DECISION_NOTIFICATION_TYPES.FEATURE
126+
| typeof DECISION_NOTIFICATION_TYPES.FEATURE_TEST
127+
| typeof DECISION_NOTIFICATION_TYPES.FEATURE_VARIABLE
128+
| typeof DECISION_NOTIFICATION_TYPES.ALL_FEATURE_VARIABLES
129+
| typeof DECISION_NOTIFICATION_TYPES.FLAG;
124130

125-
// NotificationCenter-related types
131+
export type DecisionSource =
132+
| typeof DECISION_SOURCES.FEATURE_TEST
133+
| typeof DECISION_SOURCES.ROLLOUT
134+
| typeof DECISION_SOURCES.EXPERIMENT;
135+
136+
export type DecisionSourceInfo = {
137+
experimentKey?: string;
138+
variationKey?: string;
139+
};
140+
141+
export type VariablesMap = { [variableKey: string]: unknown };
142+
143+
export type AbTestDecisionInfo = {
144+
experimentKey: string;
145+
variationKey: string | null;
146+
};
147+
148+
export type FeatureDecisionInfo = {
149+
featureKey: string;
150+
featureEnabled: boolean;
151+
source: DecisionSource;
152+
sourceInfo: DecisionSourceInfo;
153+
};
154+
155+
export type FeatureTestDecisionInfo = {
156+
experimentKey: string;
157+
variationKey: string | null;
158+
};
159+
160+
export type FeatureVariableDecisionInfo = {
161+
featureKey: string;
162+
featureEnabled: boolean;
163+
source: DecisionSource;
164+
variableKey: string;
165+
variableValue: FeatureVariableValue;
166+
variableType: VariableType;
167+
sourceInfo: DecisionSourceInfo;
168+
};
169+
170+
export type AllFeatureVariablesDecisionInfo = {
171+
featureKey: string;
172+
featureEnabled: boolean;
173+
source: DecisionSource;
174+
variableValues: VariablesMap;
175+
sourceInfo: DecisionSourceInfo;
176+
};
177+
178+
export type FlagDecisionInfo = {
179+
flagKey: string;
180+
enabled: boolean;
181+
variationKey: string | null;
182+
ruleKey: string | null;
183+
variables: VariablesMap;
184+
reasons: string[];
185+
decisionEventDispatched: boolean;
186+
experimentId?: string;
187+
variationId?: string;
188+
};
189+
190+
export type DecisionInfoMap = {
191+
[DECISION_NOTIFICATION_TYPES.AB_TEST]: AbTestDecisionInfo;
192+
[DECISION_NOTIFICATION_TYPES.FEATURE]: FeatureDecisionInfo;
193+
[DECISION_NOTIFICATION_TYPES.FEATURE_TEST]: FeatureTestDecisionInfo;
194+
[DECISION_NOTIFICATION_TYPES.FEATURE_VARIABLE]: FeatureVariableDecisionInfo;
195+
[DECISION_NOTIFICATION_TYPES.ALL_FEATURE_VARIABLES]: AllFeatureVariablesDecisionInfo;
196+
[DECISION_NOTIFICATION_TYPES.FLAG]: FlagDecisionInfo;
197+
};
198+
199+
export type DecisionListenerPayloadForType<T extends DecisionNotificationType> = ListenerPayload & {
200+
type: T;
201+
decisionInfo: DecisionInfoMap[T];
202+
};
203+
204+
export type DecisionListenerPayload = {
205+
[T in DecisionNotificationType]: DecisionListenerPayloadForType<T>;
206+
}[DecisionNotificationType];
207+
208+
export type LogEventListenerPayload = Event;
209+
210+
export type NotificationPayloadMap = {
211+
[NOTIFICATION_TYPES.ACTIVATE]: ActivateListenerPayload;
212+
[NOTIFICATION_TYPES.DECISION]: DecisionListenerPayload;
213+
[NOTIFICATION_TYPES.TRACK]: TrackListenerPayload;
214+
[NOTIFICATION_TYPES.LOG_EVENT]: LogEventListenerPayload;
215+
[NOTIFICATION_TYPES.OPTIMIZELY_CONFIG_UPDATE]: undefined;
216+
};
217+
218+
export type NotificationListener<T> = (notificationData: T) => void;
126219
export interface NotificationCenter {
127-
addNotificationListener<T extends ListenerPayload>(
128-
notificationType: string,
129-
callback: NotificationListener<T>
220+
addNotificationListener<K extends keyof NotificationPayloadMap>(
221+
notificationType: K,
222+
callback: NotificationListener<NotificationPayloadMap[K]>
130223
): number;
131224
removeNotificationListener(listenerId: number): boolean;
132225
clearAllNotificationListeners(): void;
@@ -385,14 +478,14 @@ export interface Client {
385478
}
386479

387480
export interface ActivateListenerPayload extends ListenerPayload {
388-
experiment: import('./shared_types').Experiment;
389-
variation: import('./shared_types').Variation;
481+
experiment?: import('./shared_types').Experiment;
482+
variation?: import('./shared_types').Variation;
390483
logEvent: Event;
391484
}
392485

393486
export interface TrackListenerPayload extends ListenerPayload {
394487
eventKey: string;
395-
eventTags: EventTags;
488+
eventTags?: EventTags;
396489
logEvent: Event;
397490
}
398491

lib/utils/enums/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export const DECISION_NOTIFICATION_TYPES = {
230230
FEATURE_VARIABLE: 'feature-variable',
231231
ALL_FEATURE_VARIABLES: 'all-feature-variables',
232232
FLAG: 'flag',
233-
};
233+
} as const;
234234

235235
/*
236236
* Represents the source of a decision for feature management. When a feature
@@ -242,7 +242,7 @@ export const DECISION_SOURCES = {
242242
FEATURE_TEST: 'feature-test',
243243
ROLLOUT: 'rollout',
244244
EXPERIMENT: 'experiment',
245-
};
245+
} as const;
246246

247247
export const AUDIENCE_EVALUATION_TYPES = {
248248
RULE: 'rule',

0 commit comments

Comments
 (0)