@@ -6,6 +6,7 @@ import gleam/result
6
6
import openfeature/client . { type Client , Client , ClientMetadata }
7
7
import openfeature/domain . { type Domain }
8
8
import openfeature/evaluation_context . { type EvaluationContext , EvaluationContext }
9
+ import openfeature/events . { type EventCallback }
9
10
import openfeature/provider . { type FeatureProvider , type Metadata }
10
11
import openfeature/providers/no_op
11
12
import worm
@@ -21,12 +22,15 @@ type APIMessage {
21
22
)
22
23
GetProvider ( reply_with : Subject ( FeatureProvider ) , domain : Domain )
23
24
SetContext ( evaluation_context : EvaluationContext )
25
+ AddHandler ( domain : Domain , callback : EventCallback )
26
+ RemoveHandler ( domain : Domain , callback : EventCallback )
24
27
}
25
28
26
29
type API {
27
30
API (
28
31
provider_registry : Dict ( Domain , FeatureProvider ) ,
29
32
global_context : EvaluationContext ,
33
+ event_callbacks : Dict ( Domain , List ( EventCallback ) ) ,
30
34
)
31
35
}
32
36
@@ -35,7 +39,7 @@ fn get_api_subject() -> Subject(APIMessage) {
35
39
}
36
40
37
41
fn init_api ( ) {
38
- let initial_state = API ( dict . new ( ) , evaluation_context . empty ( ) )
42
+ let initial_state = API ( dict . new ( ) , evaluation_context . empty ( ) , dict . new ( ) )
39
43
let assert Ok ( subject ) =
40
44
actor . start ( initial_state , fn ( message : APIMessage , state : API ) {
41
45
case message {
@@ -55,6 +59,14 @@ fn init_api() {
55
59
SetContext ( evaluation_context ) ->
56
60
set_context_internal ( state , evaluation_context )
57
61
|> actor . continue
62
+
63
+ AddHandler ( domain , callback ) ->
64
+ add_handler_internal ( state , domain , callback )
65
+ |> actor . continue
66
+
67
+ RemoveHandler ( domain , callback ) ->
68
+ remove_handler_internal ( state , domain , callback )
69
+ |> actor . continue
58
70
}
59
71
} )
60
72
subject
@@ -76,14 +88,14 @@ fn set_provider_internal(
76
88
domain : Domain ,
77
89
provider : FeatureProvider ,
78
90
) -> API {
79
- provider . initialize ( state . global_context )
80
- |> actor . send ( reply_with , _ )
91
+ let init_result = provider . initialize ( state . global_context )
92
+ actor . send ( reply_with , init_result )
81
93
82
94
let provider_registry =
83
95
state . provider_registry
84
96
|> dict . insert ( domain , provider )
85
97
86
- API ( provider_registry , state . global_context )
98
+ API ( provider_registry , state . global_context , state . event_callbacks )
87
99
}
88
100
89
101
fn get_provider ( ) -> FeatureProvider {
@@ -147,7 +159,7 @@ fn set_context_internal(
147
159
state : API ,
148
160
evaluation_context : EvaluationContext ,
149
161
) -> API {
150
- API ( state . provider_registry , evaluation_context )
162
+ API ( state . provider_registry , evaluation_context , state . event_callbacks )
151
163
}
152
164
153
165
pub fn shutdown ( ) {
@@ -159,3 +171,31 @@ fn shutdown_internal(state: API) -> Nil {
159
171
|> dict . values
160
172
|> list . each ( fn ( provider ) { provider . shutdown ( ) } )
161
173
}
174
+
175
+ fn add_handler_internal (
176
+ state : API ,
177
+ domain : Domain ,
178
+ callback : EventCallback ,
179
+ ) -> API {
180
+ let domain_callbacks =
181
+ state . event_callbacks
182
+ |> dict . get ( domain )
183
+ |> result . unwrap ( [ ] )
184
+ |> list . prepend ( callback )
185
+
186
+ state . event_callbacks
187
+ |> dict . insert ( domain , domain_callbacks )
188
+ |> API ( state . provider_registry , state . global_context , _)
189
+ }
190
+
191
+ fn remove_handler_internal ( state : API , domain : Domain , callback : EventCallback ) {
192
+ let domain_callbacks =
193
+ state . event_callbacks
194
+ |> dict . get ( domain )
195
+ |> result . unwrap ( [ ] )
196
+ |> list . drop_while ( fn ( x ) { x == callback } )
197
+
198
+ state . event_callbacks
199
+ |> dict . insert ( domain , domain_callbacks )
200
+ |> API ( state . provider_registry , state . global_context , _)
201
+ }
0 commit comments