@@ -30,57 +30,68 @@ const Experiments = {
30
30
// "example": 0.1,
31
31
"login-from-context-6826" : 0.5 , // https://github.com/gitpod-io/gitpod/issues/6826
32
32
} ;
33
- const ExperimentsSet = new Set ( Object . keys ( Experiments ) ) as Set < Experiment > ;
33
+ type Experiments = Partial < { [ e in Experiment ] : boolean } > ;
34
34
export type Experiment = keyof ( typeof Experiments ) ;
35
35
36
36
export namespace Experiment {
37
- export function seed ( keepCurrent : boolean ) : Set < Experiment > {
38
- const current = keepCurrent ? get ( ) : undefined ;
39
-
40
- // add all current experiments to ensure stability
41
- const result = new Set < Experiment > ( [ ...( current || [ ] ) ] . filter ( e => ExperimentsSet . has ( e ) ) ) ;
37
+ /**
38
+ * Randomly decides what the set of Experiments is the user participates in
39
+ * @param keepCurrent
40
+ * @returns Experiments
41
+ */
42
+ export function seed ( keepCurrent : boolean ) : Experiments {
43
+ const result = keepCurrent ? get ( ) || { } : { } ;
42
44
43
- // identify all new experiments and add if random
44
- const newExperiment = new Set < Experiment > ( [ ...ExperimentsSet ] . filter ( e => ! result . has ( e ) ) ) ;
45
- for ( const e of newExperiment ) {
46
- if ( Math . random ( ) < Experiments [ e ] ) {
47
- result . add ( e ) ;
45
+ for ( const experiment of Object . keys ( Experiments ) as Experiment [ ] ) {
46
+ if ( ! ( experiment in result ) ) {
47
+ result [ experiment ] = Math . random ( ) < Experiments [ experiment ] ;
48
48
}
49
49
}
50
50
51
51
return result ;
52
52
}
53
53
54
- export function set ( set : Set < Experiment > ) : void {
54
+ export function set ( set : Experiments ) : void {
55
55
try {
56
- const arr = Array . from ( set ) ;
57
- window . localStorage . setItem ( UI_EXPERIMENTS_KEY , JSON . stringify ( arr ) ) ;
56
+ window . localStorage . setItem ( UI_EXPERIMENTS_KEY , JSON . stringify ( set ) ) ;
58
57
} catch ( err ) {
59
- console . error ( `error setting ${ UI_EXPERIMENTS_KEY } ` , err ) ;
58
+ console . warn ( `error setting ${ UI_EXPERIMENTS_KEY } ` , err ) ;
60
59
}
61
60
}
62
61
63
62
export function has ( experiment : Experiment ) : boolean {
64
- const set = get ( ) ;
65
- if ( ! set ) {
63
+ try {
64
+ const set = get ( ) ;
65
+ if ( ! set ) {
66
+ return false ;
67
+ }
68
+ return set [ experiment ] === true ;
69
+ } catch ( err ) {
70
+ console . warn ( `error checking experiment '${ experiment } '` , err ) ;
66
71
return false ;
67
72
}
68
- return set . has ( experiment ) ;
69
73
}
70
74
71
- export function get ( ) : Set < Experiment > | undefined {
72
- const arr = window . localStorage . getItem ( UI_EXPERIMENTS_KEY ) ;
73
- if ( arr === null ) {
74
- return undefined ;
75
- }
76
- return new Set ( JSON . parse ( arr ) ) as Set < Experiment > ;
77
- }
75
+ /** Retrieves all currently valid Experiments from localStorage */
76
+ export function get ( ) : Experiments | undefined {
77
+ try {
78
+ const objStr = window . localStorage . getItem ( UI_EXPERIMENTS_KEY ) ;
79
+ if ( objStr === null ) {
80
+ return undefined ;
81
+ }
78
82
79
- export function getAsArray ( ) : Experiment [ ] {
80
- const set = get ( ) ;
81
- if ( ! set ) {
82
- return [ ] ;
83
+ const obj = JSON . parse ( objStr ) as Experiments ;
84
+ // trim to contain only known keys so we're type-safe
85
+ for ( const e of Object . keys ( obj ) ) {
86
+ if ( ! ( e in Experiments ) ) {
87
+ delete ( obj as any ) [ e ] ;
88
+ }
89
+ }
90
+ return obj ;
91
+ } catch ( err ) {
92
+ // we definitely don't want to break anybody because of weird errors
93
+ console . warn ( `error getting ${ UI_EXPERIMENTS_KEY } ` , err ) ;
94
+ return undefined ;
83
95
}
84
- return Array . from ( set ) ;
85
96
}
86
97
}
0 commit comments