13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
15
*/
16
-
17
16
import { LogHandler } from '../modules/logging' ;
18
17
import { Cache } from '../utils/cache/cache' ;
18
+ import { AsyncProducer , Maybe } from '../utils/type' ;
19
19
import { isVuid , makeVuid } from './vuid' ;
20
20
21
- export type VuidManagerOptions = {
22
- enableVuid : boolean ;
21
+ export interface VuidManager {
22
+ getVuid ( ) : Maybe < string > ;
23
+ isVuidEnabled ( ) : boolean ;
24
+ initialize ( ) : Promise < void > ;
23
25
}
24
26
25
- export class VuidManager {
27
+ export class VuidCacheManager {
26
28
private logger ?: LogHandler ;
27
29
private vuidCacheKey = 'optimizely-vuid' ;
28
- private vuid ?: string ;
29
- private vuidEnabled = false ;
30
30
private cache : Cache < string > ;
31
+ // if this value is not undefined, this means the same value is in the cache
32
+ // if this is undefined, it could either mean that there is no value in the cache
33
+ // or that there is a value in the cache but it has not been loaded yet
34
+ private vuid ?: string ;
31
35
private waitPromise : Promise < unknown > = Promise . resolve ( ) ;
32
36
33
- getVuid ( ) : string | undefined {
34
- return this . vuid ;
35
- }
36
-
37
- isVuidEnabled ( ) : boolean {
38
- return this . vuidEnabled ;
39
- }
40
-
41
37
constructor ( cache : Cache < string > , logger ?: LogHandler ) {
42
38
this . cache = cache ;
43
39
this . logger = logger ;
@@ -47,46 +43,79 @@ export class VuidManager {
47
43
this . logger = logger ;
48
44
}
49
45
50
- /**
51
- * Configures the VuidManager
52
- * @returns Promise that resolves when the VuidManager is configured
53
- */
54
- async configure ( options : VuidManagerOptions ) : Promise < unknown > {
55
- const configureFn = async ( ) => {
56
- this . vuidEnabled = options . enableVuid ;
57
-
58
- if ( ! this . vuidEnabled ) {
59
- await this . cache . remove ( this . vuidCacheKey ) ;
60
- this . vuid = undefined ;
61
- return ;
62
- }
63
-
64
- if ( ! this . vuid ) {
65
- await this . initializeVuid ( ) ;
66
- }
46
+ async serialize < T > ( fn : AsyncProducer < T > ) : Promise < T > {
47
+ const resultPromise = this . waitPromise . then ( fn , fn ) ;
48
+ this . waitPromise = resultPromise . catch ( ( ) => { } ) ;
49
+ return resultPromise ;
50
+ }
51
+
52
+ async remove ( ) : Promise < unknown > {
53
+ const removeFn = async ( ) => {
54
+ this . vuid = undefined ;
55
+ await this . cache . remove ( this . vuidCacheKey ) ;
67
56
}
68
57
69
- this . waitPromise = this . waitPromise . then ( configureFn , configureFn ) ;
70
- this . waitPromise . catch ( ( ) => { } ) ;
71
- return this . waitPromise ;
58
+ return this . serialize ( removeFn ) ;
72
59
}
73
60
74
- /**
75
- * Attempts to load a VUID from persistent cache or generates a new VUID
76
- * and saves it in the cache
77
- * @private
78
- */
79
- private async initializeVuid ( ) : Promise < void > {
61
+ async load ( ) : Promise < string > {
62
+ if ( this . vuid ) {
63
+ return this . vuid ;
64
+ }
65
+
80
66
const cachedValue = await this . cache . get ( this . vuidCacheKey ) ;
81
67
if ( cachedValue && isVuid ( cachedValue ) ) {
82
68
this . vuid = cachedValue ;
83
- } else {
84
- await this . save ( makeVuid ( ) ) ;
69
+ return this . vuid ;
70
+ }
71
+
72
+ const saveFn = async ( ) => {
73
+ const newVuid = makeVuid ( ) ;
74
+ await this . cache . set ( this . vuidCacheKey , newVuid ) ;
75
+ this . vuid = newVuid ;
76
+ return newVuid ;
85
77
}
78
+ return this . serialize ( saveFn ) ;
86
79
}
80
+ }
81
+
82
+ export type VuidManagerConfig = {
83
+ enableVuid ?: boolean ;
84
+ vuidCacheManager : VuidCacheManager ;
85
+ }
86
+
87
+ export class DefaultVuidManger implements VuidManager {
88
+ private vuidCacheManager : VuidCacheManager ;
89
+ private logger ?: LogHandler ;
90
+ private vuid ?: string ;
91
+ private vuidEnabled = false ;
92
+ private initialized = false ;
93
+
94
+ constructor ( config : VuidManagerConfig ) {
95
+ this . vuidCacheManager = config . vuidCacheManager ;
96
+ this . vuidEnabled = config . enableVuid || false ;
97
+ }
98
+
99
+ getVuid ( ) : Maybe < string > {
100
+ return this . vuid ;
101
+ }
102
+
103
+ isVuidEnabled ( ) : boolean {
104
+ return this . vuidEnabled ;
105
+ }
106
+
107
+ /**
108
+ * initializes the VuidManager
109
+ * @returns Promise that resolves when the VuidManager is initialized
110
+ */
111
+ async initialize ( ) : Promise < void > {
112
+ if ( ! this . vuidEnabled ) {
113
+ await this . vuidCacheManager . remove ( ) ;
114
+ this . initialized = true ;
115
+ return ;
116
+ }
87
117
88
- private async save ( vuid : string ) : Promise < void > {
89
- await this . cache . set ( this . vuidCacheKey , vuid ) ;
90
- this . vuid = vuid ;
118
+ this . vuid = await this . vuidCacheManager . load ( ) ;
119
+ this . initialized = true ;
91
120
}
92
121
}
0 commit comments