Created
April 19, 2019 00:04
-
-
Save jordangarcia/94b5448f5c4d4d4397ded98c3c10d41c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface KeyedEntity { | |
id: string | |
key: string | |
} | |
interface KeyedEntitySet<T extends KeyedEntity> { | |
getAll(): T[] | |
getKeys(): string[] | |
getById(id: string): T | null | |
getByKey(key: string): T | null | |
} | |
type VariableValue = string | boolean | number | |
enum VariableType { | |
STRING = 'string', | |
DOUBLE = 'double', | |
INTEGER = 'integer', | |
BOOLEAN = 'boolean', | |
} | |
/** | |
* Questions: | |
* 1) Does experiment status have meaning in an abtest | |
* 2) Do we need to expose the concepts of groups? | |
* 3) Is it necessary to include traffic allocation in a v1? | |
* | |
*/ | |
interface Experiment { | |
id: string | |
key: string | |
type: 'ab' | 'feature' | 'mvt' | |
variations: KeyedEntitySet<Variation> | |
trafficAllocation: ExperimentTrafficAllocation[] | |
} | |
interface Variation { | |
id: string | |
key: string | |
variables: KeyedEntitySet<Variable> | |
featuredEnabled?: boolean | |
} | |
type Variable = { | |
id: string | |
key: string | |
value: VariableValue | null | |
type: VariableType | |
} | |
type ExperimentTrafficAllocation = { | |
variationId: string | |
endOfRange: number | |
} | |
interface FeatureFlag { | |
id: string | |
key: string | |
rolloutEnabled: boolean | |
rolloutPercentage: number | |
defaultVariables: KeyedEntitySet<Variable> | |
featureExperiments: KeyedEntitySet<Experiment> | |
} | |
interface OptimizelyConfig { | |
abtests: KeyedEntitySet<Experiment> | |
featureFlags: KeyedEntitySet<FeatureFlag> | |
} | |
let optimizely = {} as ({ getOptimizelyConfig(): OptimizelyConfig }) | |
/** | |
* Access patterns | |
*/ | |
let optimizelyConfig = optimizely.getOptimizelyConfig() | |
// get all feature flags | |
optimizelyConfig.featureFlags.getAll() | |
// get all feature keys | |
optimizelyConfig.featureFlags.getKeys() | |
// get feature flag by id | |
optimizelyConfig.featureFlags.getById('123') | |
// get feature flag by key | |
optimizelyConfig.featureFlags.getByKey('feature1') | |
// get all abtests | |
optimizelyConfig.abtests.getAll() | |
// get all abtest keys | |
optimizelyConfig.abtests.getKeys() | |
// get abtest by id | |
optimizelyConfig.abtests.getById('123') | |
// get abtest by key | |
optimizelyConfig.abtests.getByKey('abtest1') | |
const exp = optimizelyConfig.abtests.getByKey('exp1') | |
if (exp) { | |
const variation1 = exp.variations.getByKey('var1') | |
} | |
// get feature by key | |
const feature1 = optimizelyConfig.featureFlags.getByKey('feature1') | |
// build variable map | |
if (feature1) { | |
let variablesMap = {} | |
const variables = feature1.defaultVariables.getAll() | |
variables.forEach(variable => { | |
switch (variable.type) { | |
case VariableType.STRING: | |
variablesMap[variable.key] = optimizely.getFeatureVariableString( | |
'feature1', | |
variable.key, | |
userId, | |
) | |
break | |
case VariableType.DOUBLE: | |
variablesMap[variable.key] = optimizely.getFeatureVariableDouble( | |
'feature1', | |
variable.key, | |
userId, | |
) | |
break | |
case VariableType.INTEGER: | |
variablesMap[variable.key] = optimizely.getFeatureVariableInteger( | |
'feature1', | |
variable.key, | |
userId, | |
) | |
break | |
case VariableType.BOOLEAN: | |
variablesMap[variable.key] = optimizely.getFeatureVariableBoolean( | |
'feature1', | |
variable.key, | |
userId, | |
) | |
break | |
} | |
}) | |
} | |
// check if a feature is rolled out to 100% | |
const feature2 = optimizelyConfig.featureFlags.getByKey('feature2') | |
const isRolledOut = | |
feature2 && feature2.rolloutEnabled && feature2.rolloutPercentage === 10000 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment