From 7ea17f394527cb33409f8a568ad6fda28503a0f8 Mon Sep 17 00:00:00 2001 From: Polina Nguen Date: Tue, 15 Sep 2020 12:05:22 -0700 Subject: [PATCH 1/9] Create index.d.ts file --- .../lib/core/decision_service/index.d.ts | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 packages/optimizely-sdk/lib/core/decision_service/index.d.ts diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts new file mode 100644 index 000000000..445f91762 --- /dev/null +++ b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts @@ -0,0 +1,151 @@ +/** + * Copyright 2018-2020, Optimizely + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { + + export interface DecisionService { + getVariation(experimentKey: string, userId: string, attributes?: UserAttributes): string | null; + // getVariationForFeature(configObj, feature, userId, attributes): + } + + export interface ConfigObj { + __datafileStr: string; + events: Event[]; + featureFlags: FeatureFlag[]; + experiments: Experiment[]; + anonymizeIP: boolean; + botFiltering: boolean; + audiences: Audience[]; + revision: string; + groups: Group[]; + attributes: UserAttributes; + rollouts: Rollout[]; + projectId: string; + accountId: string; + version: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + variables: any; //to be defined + audiencesById: {[key : string]: Audience}; + attributeKeyMap: attributeKeyMap; + groupIdMap: {[key: string]: Group}; + rolloutIdMap: {[key:string]: Rollout}; + experimentKeyMap: {[key: string]: Experiment} //look into this one closer + experimentIdMap: {[key: string]: Experiment}; + variationIdMap: {[key: string]: Variation}; + variationVariableUsageMap: {[key: string]: ExperimentVariableByID}; + experimentFeatureMap: {[key: string]: string[]}; + featureKeyMap: {[key: string]: FeatureFlag}; //look into this one closer + } + + interface Event { + key: string; + id: string; + experimentIds: string[] + } + + interface FeatureFlag { + rolloutId: string; + key: string; + id: string; + experimentIds: string[], + variables: FeatureVariable[], + variableKeyMap: {[key: string]: FeatureVariable} + } + + interface FeatureVariable { + type: string; + key: string; + id: string; + defaultValue: string; + } + + export interface Experiment { + id: string; + key: string; + status: string; + layerId: string; + variations: Variation[]; + trafficAllocation: Array; + audienceIds: string[]; + // TODO[OASIS-6649]: Don't use object type + // eslint-disable-next-line @typescript-eslint/ban-types + forcedVariations: object; + variationKeyMap: {[key: string]: Variation} + } + + export interface Variation { + id: string; + key: string; + featureEnabled: boolean; + variables: ExperimentVariable[]; + } + + interface Audience { + id: string; + name: string; + conditions: ConditionTree; + } + + interface Group { + policy: string; + id: string; + experiments: Experiment[]; + trafficAllocation: Array; + } + + type UserAttributes = { + // TODO[OASIS-6649]: Don't use any type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [name: string]: any; + } + + type Condition = { + name: string; + type: string; + match?: string; + value: string | number | boolean | null; + } + + interface TrafficAllocationEntity { + endOfRange: number; + entityId: string; + } + + type ConditionTree = Leaf | unknown[]; + + + interface Rollout { + id: string; + experiments: Experiment[]; + } + + interface Attribute { + id: string; + key: string; + } + + interface attributeKeyMap { + [key: string]: Attribute; + } + + type ExperimentVariable = { + id: string; + value: string; + } + type ExperimentVariableByID = { + [key: string]: ExperimentVariable + } +} From 7b0a28d34a4c54b5a2fbb4b5053bf1cc596f7557 Mon Sep 17 00:00:00 2001 From: Polina Nguen Date: Tue, 15 Sep 2020 15:02:22 -0700 Subject: [PATCH 2/9] Define DecisionService and createDecisionService interfaces --- .../lib/core/decision_service/index.d.ts | 58 ++++++++++++++----- packages/optimizely-sdk/lib/index.d.ts | 16 +---- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts index 445f91762..779046be0 100644 --- a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts +++ b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2018-2020, Optimizely + * Copyright 2020, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,40 @@ */ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { + import { LogHandler } from '@optimizely/js-sdk-logging'; - export interface DecisionService { + export function createDecisionService(options: Options): DecisionService; + + export interface UserProfileService { + lookup(userId: string): UserProfile; + save(profile: UserProfile): void; + } + + interface DecisionService { getVariation(experimentKey: string, userId: string, attributes?: UserAttributes): string | null; - // getVariationForFeature(configObj, feature, userId, attributes): + getVariationForFeature(configObj: ConfigObj, feature: FeatureFlag, userId: string, attributes: unknown): Decision; + removeForcedVariation(userId: unknown, experimentId: string, experimentKey: string): void; + getForcedVariation(configObj: ConfigObj, experimentKey: string, userId: string): string | null; + setForcedVariation(configObj: ConfigObj, experimentKey: string, userId: string, variationKey: unknown): boolean; + } + + // Information about past bucketing decisions for a user. + interface UserProfile { + user_id: string; + experiment_bucket_map: { + [experiment_id: string]: { + variation_id: string; + }; + }; + } + + interface Options { + userProfileService: UserProfileService | null; + logger: LogHandler; + UNSTABLE_conditionEvaluators: unknown; } - export interface ConfigObj { - __datafileStr: string; + interface ConfigObj { events: Event[]; featureFlags: FeatureFlag[]; experiments: Experiment[]; @@ -62,7 +88,7 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { id: string; experimentIds: string[], variables: FeatureVariable[], - variableKeyMap: {[key: string]: FeatureVariable} + variableKeyMap?: {[key: string]: FeatureVariable} //look into this one closer } interface FeatureVariable { @@ -72,7 +98,7 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { defaultValue: string; } - export interface Experiment { + interface Experiment { id: string; key: string; status: string; @@ -83,10 +109,10 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { // TODO[OASIS-6649]: Don't use object type // eslint-disable-next-line @typescript-eslint/ban-types forcedVariations: object; - variationKeyMap: {[key: string]: Variation} + variationKeyMap: {[key: string]: Variation} //look into it closer } - export interface Variation { + interface Variation { id: string; key: string; featureEnabled: boolean; @@ -119,14 +145,13 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { value: string | number | boolean | null; } + type ConditionTree = Leaf | unknown[]; + interface TrafficAllocationEntity { endOfRange: number; entityId: string; } - type ConditionTree = Leaf | unknown[]; - - interface Rollout { id: string; experiments: Experiment[]; @@ -145,7 +170,14 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { id: string; value: string; } + type ExperimentVariableByID = { - [key: string]: ExperimentVariable + [key: string]: ExperimentVariable; + } + + interface Decision { + experiment: Experiment | null; + variation: Variation | null; + decisionSource: string; } } diff --git a/packages/optimizely-sdk/lib/index.d.ts b/packages/optimizely-sdk/lib/index.d.ts index 3f110095f..da10bf09d 100644 --- a/packages/optimizely-sdk/lib/index.d.ts +++ b/packages/optimizely-sdk/lib/index.d.ts @@ -16,6 +16,7 @@ declare module '@optimizely/optimizely-sdk' { import { LogHandler, ErrorHandler } from '@optimizely/js-sdk-logging'; + import { UserProfileService } from '@optimizely/optimizely-sdk/lib/core/decision_service'; import * as enums from '@optimizely/optimizely-sdk/lib/utils/enums'; import * as logging from '@optimizely/optimizely-sdk/lib/plugins/logger'; export { enums, logging }; @@ -135,11 +136,6 @@ declare module '@optimizely/optimizely-sdk' { dispatchEvent: (event: Event, callback: () => void) => void; } - export interface UserProfileService { - lookup: (userId: string) => UserProfile; - save: (profile: UserProfile) => void; - } - // NotificationCenter-related types export interface NotificationCenter { addNotificationListener( @@ -201,16 +197,6 @@ declare module '@optimizely/optimizely-sdk' { key: string; } - // Information about past bucketing decisions for a user. - export interface UserProfile { - user_id: string; - experiment_bucket_map: { - [experiment_id: string]: { - variation_id: string; - }; - }; - } - /** * Optimizely Config Entities */ From a9289ffc62402a16bcdfd2bf71fbb823088bacf3 Mon Sep 17 00:00:00 2001 From: Polina Nguen Date: Tue, 15 Sep 2020 16:43:10 -0700 Subject: [PATCH 3/9] Clean up --- .../lib/core/decision_service/index.d.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts index 779046be0..afa3158fb 100644 --- a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts +++ b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts @@ -62,18 +62,17 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { projectId: string; accountId: string; version: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - variables: any; //to be defined + variables: FeatureVariable[]; audiencesById: {[key : string]: Audience}; attributeKeyMap: attributeKeyMap; groupIdMap: {[key: string]: Group}; rolloutIdMap: {[key:string]: Rollout}; - experimentKeyMap: {[key: string]: Experiment} //look into this one closer + experimentKeyMap: {[key: string]: Experiment} experimentIdMap: {[key: string]: Experiment}; variationIdMap: {[key: string]: Variation}; variationVariableUsageMap: {[key: string]: ExperimentVariableByID}; experimentFeatureMap: {[key: string]: string[]}; - featureKeyMap: {[key: string]: FeatureFlag}; //look into this one closer + featureKeyMap: {[key: string]: FeatureFlag}; } interface Event { @@ -88,11 +87,12 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { id: string; experimentIds: string[], variables: FeatureVariable[], - variableKeyMap?: {[key: string]: FeatureVariable} //look into this one closer + variableKeyMap?: {[key: string]: FeatureVariable} } interface FeatureVariable { type: string; + subType?: string; key: string; id: string; defaultValue: string; @@ -109,7 +109,7 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { // TODO[OASIS-6649]: Don't use object type // eslint-disable-next-line @typescript-eslint/ban-types forcedVariations: object; - variationKeyMap: {[key: string]: Variation} //look into it closer + variationKeyMap?: {[key: string]: Variation}; } interface Variation { From c83b2d2ac0b6d311f82d717e0d4d50d22b0e9be1 Mon Sep 17 00:00:00 2001 From: uzair-folio3 Date: Tue, 15 Sep 2020 19:59:44 +0500 Subject: [PATCH 4/9] index.d.ts added for project_config --- packages/optimizely-sdk/lib/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/optimizely-sdk/lib/index.d.ts b/packages/optimizely-sdk/lib/index.d.ts index da10bf09d..07970bd8e 100644 --- a/packages/optimizely-sdk/lib/index.d.ts +++ b/packages/optimizely-sdk/lib/index.d.ts @@ -176,7 +176,7 @@ declare module '@optimizely/optimizely-sdk' { logEvent: Event; } - interface Experiment { + export interface Experiment { id: string; key: string; status: string; @@ -192,7 +192,7 @@ declare module '@optimizely/optimizely-sdk' { forcedVariations: object; } - interface Variation { + export interface Variation { id: string; key: string; } From a0805d72d63afe0fc43d5070894c8493696fe092 Mon Sep 17 00:00:00 2001 From: Polina Nguen Date: Thu, 17 Sep 2020 09:05:53 -0700 Subject: [PATCH 5/9] Fix imports --- .../lib/core/decision_service/index.d.ts | 148 +----------------- packages/optimizely-sdk/lib/index.d.ts | 34 ++-- 2 files changed, 21 insertions(+), 161 deletions(-) diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts index afa3158fb..0162b91dd 100644 --- a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts +++ b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts @@ -14,8 +14,11 @@ * limitations under the License. */ -declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { +declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { import { LogHandler } from '@optimizely/js-sdk-logging'; + import { UserProfile, UserAttributes } from '@optimizely/optimizely-sdk'; + import { ProjectConfig } from '@optimizely/optimizely-sdk/lib/core/project_config'; + import { Experiment, Variation, FeatureFlag } from '@optimizely/optimizely-sdk/lib/core/project_config'; export function createDecisionService(options: Options): DecisionService; @@ -26,20 +29,10 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { interface DecisionService { getVariation(experimentKey: string, userId: string, attributes?: UserAttributes): string | null; - getVariationForFeature(configObj: ConfigObj, feature: FeatureFlag, userId: string, attributes: unknown): Decision; + getVariationForFeature(configObj: ProjectConfig, feature: FeatureFlag, userId: string, attributes: unknown): Decision; removeForcedVariation(userId: unknown, experimentId: string, experimentKey: string): void; - getForcedVariation(configObj: ConfigObj, experimentKey: string, userId: string): string | null; - setForcedVariation(configObj: ConfigObj, experimentKey: string, userId: string, variationKey: unknown): boolean; - } - - // Information about past bucketing decisions for a user. - interface UserProfile { - user_id: string; - experiment_bucket_map: { - [experiment_id: string]: { - variation_id: string; - }; - }; + getForcedVariation(configObj: ProjectConfig, experimentKey: string, userId: string): string | null; + setForcedVariation(configObj: ProjectConfig, experimentKey: string, userId: string, variationKey: unknown): boolean; } interface Options { @@ -48,133 +41,6 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { UNSTABLE_conditionEvaluators: unknown; } - interface ConfigObj { - events: Event[]; - featureFlags: FeatureFlag[]; - experiments: Experiment[]; - anonymizeIP: boolean; - botFiltering: boolean; - audiences: Audience[]; - revision: string; - groups: Group[]; - attributes: UserAttributes; - rollouts: Rollout[]; - projectId: string; - accountId: string; - version: string; - variables: FeatureVariable[]; - audiencesById: {[key : string]: Audience}; - attributeKeyMap: attributeKeyMap; - groupIdMap: {[key: string]: Group}; - rolloutIdMap: {[key:string]: Rollout}; - experimentKeyMap: {[key: string]: Experiment} - experimentIdMap: {[key: string]: Experiment}; - variationIdMap: {[key: string]: Variation}; - variationVariableUsageMap: {[key: string]: ExperimentVariableByID}; - experimentFeatureMap: {[key: string]: string[]}; - featureKeyMap: {[key: string]: FeatureFlag}; - } - - interface Event { - key: string; - id: string; - experimentIds: string[] - } - - interface FeatureFlag { - rolloutId: string; - key: string; - id: string; - experimentIds: string[], - variables: FeatureVariable[], - variableKeyMap?: {[key: string]: FeatureVariable} - } - - interface FeatureVariable { - type: string; - subType?: string; - key: string; - id: string; - defaultValue: string; - } - - interface Experiment { - id: string; - key: string; - status: string; - layerId: string; - variations: Variation[]; - trafficAllocation: Array; - audienceIds: string[]; - // TODO[OASIS-6649]: Don't use object type - // eslint-disable-next-line @typescript-eslint/ban-types - forcedVariations: object; - variationKeyMap?: {[key: string]: Variation}; - } - - interface Variation { - id: string; - key: string; - featureEnabled: boolean; - variables: ExperimentVariable[]; - } - - interface Audience { - id: string; - name: string; - conditions: ConditionTree; - } - - interface Group { - policy: string; - id: string; - experiments: Experiment[]; - trafficAllocation: Array; - } - - type UserAttributes = { - // TODO[OASIS-6649]: Don't use any type - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [name: string]: any; - } - - type Condition = { - name: string; - type: string; - match?: string; - value: string | number | boolean | null; - } - - type ConditionTree = Leaf | unknown[]; - - interface TrafficAllocationEntity { - endOfRange: number; - entityId: string; - } - - interface Rollout { - id: string; - experiments: Experiment[]; - } - - interface Attribute { - id: string; - key: string; - } - - interface attributeKeyMap { - [key: string]: Attribute; - } - - type ExperimentVariable = { - id: string; - value: string; - } - - type ExperimentVariableByID = { - [key: string]: ExperimentVariable; - } - interface Decision { experiment: Experiment | null; variation: Variation | null; diff --git a/packages/optimizely-sdk/lib/index.d.ts b/packages/optimizely-sdk/lib/index.d.ts index 07970bd8e..7d156e18e 100644 --- a/packages/optimizely-sdk/lib/index.d.ts +++ b/packages/optimizely-sdk/lib/index.d.ts @@ -16,7 +16,7 @@ declare module '@optimizely/optimizely-sdk' { import { LogHandler, ErrorHandler } from '@optimizely/js-sdk-logging'; - import { UserProfileService } from '@optimizely/optimizely-sdk/lib/core/decision_service'; + import { Experiment, Variation } from '@optimizely/optimizely-sdk/lib/core/project_config'; import * as enums from '@optimizely/optimizely-sdk/lib/utils/enums'; import * as logging from '@optimizely/optimizely-sdk/lib/plugins/logger'; export { enums, logging }; @@ -136,6 +136,11 @@ declare module '@optimizely/optimizely-sdk' { dispatchEvent: (event: Event, callback: () => void) => void; } + export interface UserProfileService { + lookup: (userId: string) => UserProfile; + save: (profile: UserProfile) => void; + } + // NotificationCenter-related types export interface NotificationCenter { addNotificationListener( @@ -176,25 +181,14 @@ declare module '@optimizely/optimizely-sdk' { logEvent: Event; } - export interface Experiment { - id: string; - key: string; - status: string; - layerId: string; - variations: Variation[]; - trafficAllocation: Array<{ - entityId: string; - endOfRange: number; - }>; - audienceIds: string[]; - // TODO[OASIS-6649]: Don't use object type - // eslint-disable-next-line @typescript-eslint/ban-types - forcedVariations: object; - } - - export interface Variation { - id: string; - key: string; + // Information about past bucketing decisions for a user. + export interface UserProfile { + user_id: string; + experiment_bucket_map: { + [experiment_id: string]: { + variation_id: string; + }; + }; } /** From 2b495c546b89e49c245ef7b74de0165f7b00fc31 Mon Sep 17 00:00:00 2001 From: Polina Nguen Date: Thu, 17 Sep 2020 10:36:08 -0700 Subject: [PATCH 6/9] Fix imports to avoid anti-pattern --- .../lib/core/decision_service/index.d.ts | 20 ++++++++++++++--- packages/optimizely-sdk/lib/index.d.ts | 22 +------------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts index 0162b91dd..8d5ae6a90 100644 --- a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts +++ b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts @@ -16,9 +16,7 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { import { LogHandler } from '@optimizely/js-sdk-logging'; - import { UserProfile, UserAttributes } from '@optimizely/optimizely-sdk'; - import { ProjectConfig } from '@optimizely/optimizely-sdk/lib/core/project_config'; - import { Experiment, Variation, FeatureFlag } from '@optimizely/optimizely-sdk/lib/core/project_config'; + import { ProjectConfig, Experiment, Variation, FeatureFlag } from '@optimizely/optimizely-sdk/lib/core/project_config'; export function createDecisionService(options: Options): DecisionService; @@ -27,6 +25,12 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { save(profile: UserProfile): void; } + export type UserAttributes = { + // TODO[OASIS-6649]: Don't use any type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [name: string]: any; + } + interface DecisionService { getVariation(experimentKey: string, userId: string, attributes?: UserAttributes): string | null; getVariationForFeature(configObj: ProjectConfig, feature: FeatureFlag, userId: string, attributes: unknown): Decision; @@ -46,4 +50,14 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { variation: Variation | null; decisionSource: string; } + + // Information about past bucketing decisions for a user. + interface UserProfile { + user_id: string; + experiment_bucket_map: { + [experiment_id: string]: { + variation_id: string; + }; + }; + } } diff --git a/packages/optimizely-sdk/lib/index.d.ts b/packages/optimizely-sdk/lib/index.d.ts index 7d156e18e..205585c74 100644 --- a/packages/optimizely-sdk/lib/index.d.ts +++ b/packages/optimizely-sdk/lib/index.d.ts @@ -17,6 +17,7 @@ declare module '@optimizely/optimizely-sdk' { import { LogHandler, ErrorHandler } from '@optimizely/js-sdk-logging'; import { Experiment, Variation } from '@optimizely/optimizely-sdk/lib/core/project_config'; + import { UserProfileService, UserAttributes } from '@optimizely/optimizely-sdk/lib/core/decision_service'; import * as enums from '@optimizely/optimizely-sdk/lib/utils/enums'; import * as logging from '@optimizely/optimizely-sdk/lib/plugins/logger'; export { enums, logging }; @@ -136,11 +137,6 @@ declare module '@optimizely/optimizely-sdk' { dispatchEvent: (event: Event, callback: () => void) => void; } - export interface UserProfileService { - lookup: (userId: string) => UserProfile; - save: (profile: UserProfile) => void; - } - // NotificationCenter-related types export interface NotificationCenter { addNotificationListener( @@ -165,12 +161,6 @@ declare module '@optimizely/optimizely-sdk' { logEvent: Event; } - export type UserAttributes = { - // TODO[OASIS-6649]: Don't use any type - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [name: string]: any; - }; - export type EventTags = { [key: string]: string | number | boolean; }; @@ -181,16 +171,6 @@ declare module '@optimizely/optimizely-sdk' { logEvent: Event; } - // Information about past bucketing decisions for a user. - export interface UserProfile { - user_id: string; - experiment_bucket_map: { - [experiment_id: string]: { - variation_id: string; - }; - }; - } - /** * Optimizely Config Entities */ From bf1389586fc43cbacef8f984948c0051cb97ae0b Mon Sep 17 00:00:00 2001 From: Polina Nguen Date: Wed, 23 Sep 2020 14:22:26 -0700 Subject: [PATCH 7/9] Add comments and clean up exports --- .../lib/core/decision_service/index.d.ts | 90 +++++++++++++------ packages/optimizely-sdk/lib/index.d.ts | 59 ++++++++---- packages/optimizely-sdk/lib/shared_types.ts | 42 ++++++++- 3 files changed, 144 insertions(+), 47 deletions(-) diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts index 8d5ae6a90..1c9104e9a 100644 --- a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts +++ b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts @@ -16,48 +16,86 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { import { LogHandler } from '@optimizely/js-sdk-logging'; - import { ProjectConfig, Experiment, Variation, FeatureFlag } from '@optimizely/optimizely-sdk/lib/core/project_config'; + import { ProjectConfig } from '@optimizely/optimizely-sdk/lib/core/project_config'; export function createDecisionService(options: Options): DecisionService; - export interface UserProfileService { - lookup(userId: string): UserProfile; - save(profile: UserProfile): void; - } + interface DecisionService { - export type UserAttributes = { - // TODO[OASIS-6649]: Don't use any type - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [name: string]: any; - } + /** + * Gets variation where visitor will be bucketed. + * @param {Object} configObj The parsed project configuration object + * @param {string} experimentKey + * @param {string} userId + * @param {Object} attributes + * @return {string|null} The variation the user is bucketed into. + */ + getVariation( + experimentKey: string, + userId: string, + attributes?: import('../../shared_types').UserAttributes + ): string | null; - interface DecisionService { - getVariation(experimentKey: string, userId: string, attributes?: UserAttributes): string | null; - getVariationForFeature(configObj: ProjectConfig, feature: FeatureFlag, userId: string, attributes: unknown): Decision; + /** + * Given a feature, user ID, and attributes, returns an object representing a + * decision. If the user was bucketed into a variation for the given feature + * and attributes, the returned decision object will have variation and + * experiment properties (both objects), as well as a decisionSource property. + * decisionSource indicates whether the decision was due to a rollout or an + * experiment. + * @param {ProjectConfig} configObj The parsed project configuration object + * @param {FeatureFlag} feature A feature flag object from project configuration + * @param {string} userId A string identifying the user, for bucketing + * @param {unknown} attributes Optional user attributes + * @return {Decision} An object with experiment, variation, and decisionSource + * properties. If the user was not bucketed into a variation, the variation + * property is null. + */ + getVariationForFeature( + configObj: ProjectConfig, + feature: import('../project_config/entities').FeatureFlag, + userId: string, + attributes: unknown + ): Decision; + + /** + * Removes forced variation for given userId and experimentKey + * @param {unknown} userId String representing the user id + * @param {string} experimentId Number representing the experiment id + * @param {string} experimentKey Key representing the experiment id + * @throws If the user id is not valid or not in the forced variation map + */ removeForcedVariation(userId: unknown, experimentId: string, experimentKey: string): void; + + /** + * Gets the forced variation key for the given user and experiment. + * @param {ProjectConfig} configObj Object representing project configuration + * @param {string} experimentKey Key for experiment. + * @param {string} userId The user Id. + * @return {string|null} Variation key that specifies the variation which the given user and experiment should be forced into. + */ getForcedVariation(configObj: ProjectConfig, experimentKey: string, userId: string): string | null; + + /** + * Sets the forced variation for a user in a given experiment + * @param {ProjectConfig} configObj Object representing project configuration + * @param {string} experimentKey Key for experiment. + * @param {string} userId The user Id. + * @param {unknown} variationKey Key for variation. If null, then clear the existing experiment-to-variation mapping + * @return {boolean} A boolean value that indicates if the set completed successfully. + */ setForcedVariation(configObj: ProjectConfig, experimentKey: string, userId: string, variationKey: unknown): boolean; } interface Options { - userProfileService: UserProfileService | null; + userProfileService: import('../../shared_types').UserProfileService | null; logger: LogHandler; UNSTABLE_conditionEvaluators: unknown; } interface Decision { - experiment: Experiment | null; - variation: Variation | null; + experiment: import('../../shared_types').Experiment | null; + variation: import('../../shared_types').Variation | null; decisionSource: string; } - - // Information about past bucketing decisions for a user. - interface UserProfile { - user_id: string; - experiment_bucket_map: { - [experiment_id: string]: { - variation_id: string; - }; - }; - } } diff --git a/packages/optimizely-sdk/lib/index.d.ts b/packages/optimizely-sdk/lib/index.d.ts index 205585c74..c18841e3d 100644 --- a/packages/optimizely-sdk/lib/index.d.ts +++ b/packages/optimizely-sdk/lib/index.d.ts @@ -16,8 +16,6 @@ declare module '@optimizely/optimizely-sdk' { import { LogHandler, ErrorHandler } from '@optimizely/js-sdk-logging'; - import { Experiment, Variation } from '@optimizely/optimizely-sdk/lib/core/project_config'; - import { UserProfileService, UserAttributes } from '@optimizely/optimizely-sdk/lib/core/decision_service'; import * as enums from '@optimizely/optimizely-sdk/lib/utils/enums'; import * as logging from '@optimizely/optimizely-sdk/lib/plugins/logger'; export { enums, logging }; @@ -57,7 +55,7 @@ declare module '@optimizely/optimizely-sdk' { // TODO[OASIS-6649]: Don't use object type // eslint-disable-next-line @typescript-eslint/ban-types jsonSchemaValidator?: object; - userProfileService?: UserProfileService | null; + userProfileService?: import('./shared_types').UserProfileService | null; eventBatchSize?: number; eventFlushInterval?: number; sdkKey?: string; @@ -65,48 +63,73 @@ declare module '@optimizely/optimizely-sdk' { export interface Client { notificationCenter: NotificationCenter; - activate(experimentKey: string, userId: string, attributes?: UserAttributes): string | null; - track(eventKey: string, userId: string, attributes?: UserAttributes, eventTags?: EventTags): void; - getVariation(experimentKey: string, userId: string, attributes?: UserAttributes): string | null; + activate( + experimentKey: string, + userId: string, + attributes?: import('./shared_types').UserAttributes + ): string | null; + track( + eventKey: string, + userId: string, + attributes?: import('./shared_types').UserAttributes, + eventTags?: EventTags + ): void; + getVariation( + experimentKey: string, + userId: string, + attributes?: import('./shared_types').UserAttributes + ): string | null; setForcedVariation(experimentKey: string, userId: string, variationKey: string | null): boolean; getForcedVariation(experimentKey: string, userId: string): string | null; - isFeatureEnabled(featureKey: string, userId: string, attributes?: UserAttributes): boolean; - getEnabledFeatures(userId: string, attributes?: UserAttributes): string[]; - getFeatureVariable(featureKey: string, variableKey: string, userId: string, attributes?: UserAttributes): unknown + isFeatureEnabled( + featureKey: string, + userId: string, + attributes?: import('./shared_types').UserAttributes + ): boolean; + getEnabledFeatures( + userId: string, + attributes?: import('./shared_types').UserAttributes + ): string[]; + getFeatureVariable( + featureKey: string, + variableKey: string, + userId: string, + attributes?: import('./shared_types').UserAttributes + ): unknown; getFeatureVariableBoolean( featureKey: string, variableKey: string, userId: string, - attributes?: UserAttributes + attributes?: import('./shared_types').UserAttributes ): boolean | null; getFeatureVariableDouble( featureKey: string, variableKey: string, userId: string, - attributes?: UserAttributes + attributes?: import('./shared_types').UserAttributes ): number | null; getFeatureVariableInteger( featureKey: string, variableKey: string, userId: string, - attributes?: UserAttributes + attributes?: import('./shared_types').UserAttributes ): number | null; getFeatureVariableString( featureKey: string, variableKey: string, userId: string, - attributes?: UserAttributes + attributes?: import('./shared_types').UserAttributes ): string | null; getFeatureVariableJSON( featureKey: string, variableKey: string, userId: string, - attributes?: UserAttributes + attributes?: import('./shared_types').UserAttributes ): unknown; getAllFeatureVariables( featureKey: string, userId: string, - attributes?: UserAttributes + attributes?: import('./shared_types').UserAttributes ): { [variableKey: string]: unknown }; getOptimizelyConfig(): OptimizelyConfig | null; onReady(options?: { timeout?: number }): Promise<{ success: boolean; reason?: string }>; @@ -152,12 +175,12 @@ declare module '@optimizely/optimizely-sdk' { export interface ListenerPayload { userId: string; - attributes: UserAttributes; + attributes: import('./shared_types').UserAttributes; } export interface ActivateListenerPayload extends ListenerPayload { - experiment: Experiment; - variation: Variation; + experiment: import('./shared_types').Experiment; + variation: import('./shared_types').Variation; logEvent: Event; } diff --git a/packages/optimizely-sdk/lib/shared_types.ts b/packages/optimizely-sdk/lib/shared_types.ts index 90324a9f6..94f86d84a 100644 --- a/packages/optimizely-sdk/lib/shared_types.ts +++ b/packages/optimizely-sdk/lib/shared_types.ts @@ -1,5 +1,41 @@ export type UserAttributes = { - // TODO[OASIS-6649]: Don't use any type - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [name: string]: any; + // TODO[OASIS-6649]: Don't use any type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [name: string]: any; +} + +export interface Variation { + id: string; + key: string; +} + +export interface Experiment { + id: string; + key: string; + status: string; + layerId: string; + variations: Variation[]; + trafficAllocation: Array<{ + entityId: string; + endOfRange: number; + }>; + audienceIds: string[]; + // TODO[OASIS-6649]: Don't use object type + // eslint-disable-next-line @typescript-eslint/ban-types + forcedVariations: object; +} + +// Information about past bucketing decisions for a user. +export interface UserProfile { + user_id: string; + experiment_bucket_map: { + [experiment_id: string]: { + variation_id: string; + }; + }; +} + +export interface UserProfileService { + lookup(userId: string): UserProfile; + save(profile: UserProfile): void; } From 89856e76f6cd503b19e6e478434b98fe0c8c0f8d Mon Sep 17 00:00:00 2001 From: Polina Nguen Date: Wed, 23 Sep 2020 14:27:46 -0700 Subject: [PATCH 8/9] Add one more comment --- packages/optimizely-sdk/lib/core/decision_service/index.d.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts index 1c9104e9a..0b8b2e6d6 100644 --- a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts +++ b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts @@ -18,6 +18,11 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { import { LogHandler } from '@optimizely/js-sdk-logging'; import { ProjectConfig } from '@optimizely/optimizely-sdk/lib/core/project_config'; + /** + * Creates an instance of the DecisionService. + * @param {Options} options Configuration options + * @return {DecisionService} An instance of the DecisionService + */ export function createDecisionService(options: Options): DecisionService; interface DecisionService { From 3dcda32b8ecd1fd9b21c8a4d12204f7bac9fbe9c Mon Sep 17 00:00:00 2001 From: Polina Nguen Date: Wed, 23 Sep 2020 14:32:57 -0700 Subject: [PATCH 9/9] Add missing attribute --- .../lib/core/decision_service/index.d.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts index 0b8b2e6d6..0daf24b22 100644 --- a/packages/optimizely-sdk/lib/core/decision_service/index.d.ts +++ b/packages/optimizely-sdk/lib/core/decision_service/index.d.ts @@ -20,7 +20,7 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { /** * Creates an instance of the DecisionService. - * @param {Options} options Configuration options + * @param {Options} options Configuration options * @return {DecisionService} An instance of the DecisionService */ export function createDecisionService(options: Options): DecisionService; @@ -29,13 +29,14 @@ declare module '@optimizely/optimizely-sdk/lib/core/decision_service' { /** * Gets variation where visitor will be bucketed. - * @param {Object} configObj The parsed project configuration object - * @param {string} experimentKey - * @param {string} userId - * @param {Object} attributes - * @return {string|null} The variation the user is bucketed into. + * @param {ProjectConfig} configObj The parsed project configuration object + * @param {string} experimentKey + * @param {string} userId + * @param {UserAttributes} attributes + * @return {string|null} The variation the user is bucketed into. */ getVariation( + configObj: ProjectConfig, experimentKey: string, userId: string, attributes?: import('../../shared_types').UserAttributes