statsig 1.31.1 → 1.32.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/statsig.rb CHANGED
@@ -1,13 +1,9 @@
1
- # typed: true
2
-
3
1
  require 'statsig_driver'
4
- require 'sorbet-runtime'
2
+
5
3
  require 'statsig_errors'
6
4
 
7
5
  module Statsig
8
- extend T::Sig
9
6
 
10
- sig { params(secret_key: String, options: T.any(StatsigOptions, NilClass), error_callback: T.any(Method, Proc, NilClass)).void }
11
7
  ##
12
8
  # Initializes the Statsig SDK.
13
9
  #
@@ -21,46 +17,54 @@ module Statsig
21
17
  return @shared_instance
22
18
  end
23
19
 
24
- self.bind_sorbet_loggers(options)
25
-
26
20
  @shared_instance = StatsigDriver.new(secret_key, options, error_callback)
27
21
  end
28
22
 
29
- class GetGateOptions < T::Struct
30
- prop :disable_log_exposure, T::Boolean, default: false
31
- prop :skip_evaluation, T::Boolean, default: false
23
+ class GetGateOptions
24
+ attr_accessor :disable_log_exposure, :skip_evaluation, :disable_evaluation_details
25
+
26
+ def initialize(disable_log_exposure: false, skip_evaluation: false, disable_evaluation_details: false)
27
+ @disable_log_exposure = disable_log_exposure
28
+ @skip_evaluation = skip_evaluation
29
+ @disable_evaluation_details = disable_evaluation_details
30
+ end
32
31
  end
33
32
 
34
- sig { params(user: StatsigUser, gate_name: String, options: GetGateOptions).returns(FeatureGate) }
35
33
  ##
36
34
  # Gets the gate, evaluated against the given user. An exposure event will automatically be logged for the gate.
37
35
  #
38
- # @param user A StatsigUser object used for the evaluation
39
- # @param gate_name The name of the gate being checked
40
- # @param options Additional options for evaluating the gate
41
- def self.get_gate(user, gate_name, options = GetGateOptions.new)
36
+ # @param [StatsigUser] user A StatsigUser object used for the evaluation
37
+ # @param [String] gate_name The name of the gate being checked
38
+ # @param [GetGateOptions] options Additional options for evaluating the gate
39
+ # @return [FeatureGate]
40
+ def self.get_gate(user, gate_name, options)
42
41
  ensure_initialized
43
42
  @shared_instance&.get_gate(user, gate_name, options)
44
43
  end
45
44
 
46
- class CheckGateOptions < T::Struct
47
- prop :disable_log_exposure, T::Boolean, default: false
45
+ class CheckGateOptions
46
+ attr_accessor :disable_log_exposure, :disable_evaluation_details
47
+
48
+ def initialize(disable_log_exposure: false, disable_evaluation_details: false)
49
+ @disable_log_exposure = disable_log_exposure
50
+ @disable_evaluation_details = disable_evaluation_details
51
+ end
48
52
  end
49
53
 
50
- sig { params(user: StatsigUser, gate_name: String, options: CheckGateOptions).returns(T::Boolean) }
51
54
  ##
52
55
  # Gets the boolean result of a gate, evaluated against the given user. An exposure event will automatically be logged for the gate.
53
56
  #
54
- # @param user A StatsigUser object used for the evaluation
55
- # @param gate_name The name of the gate being checked
56
- # @param options Additional options for evaluating the gate
57
- def self.check_gate(user, gate_name, options = CheckGateOptions.new)
57
+ # @param [StatsigUser] user A StatsigUser object used for the evaluation
58
+ # @param [String] gate_name The name of the gate being checked
59
+ # @param [CheckGateOptions] options Additional options for evaluating the gate
60
+ # @return [Boolean]
61
+ def self.check_gate(user, gate_name, options = nil)
58
62
  ensure_initialized
59
63
  @shared_instance&.check_gate(user, gate_name, options)
60
64
  end
61
65
 
62
- sig { params(user: StatsigUser, gate_name: String).returns(T::Boolean) }
63
66
  ##
67
+ # @deprecated - use check_gate(user, gate, options) and disable_exposure_logging in options
64
68
  # Gets the boolean result of a gate, evaluated against the given user.
65
69
  #
66
70
  # @param user A StatsigUser object used for the evaluation
@@ -70,7 +74,6 @@ module Statsig
70
74
  @shared_instance&.check_gate(user, gate_name, CheckGateOptions.new(disable_log_exposure: true))
71
75
  end
72
76
 
73
- sig { params(user: StatsigUser, gate_name: String).void }
74
77
  ##
75
78
  # Logs an exposure event for the gate
76
79
  #
@@ -81,34 +84,39 @@ module Statsig
81
84
  @shared_instance&.manually_log_gate_exposure(user, gate_name)
82
85
  end
83
86
 
84
- class GetConfigOptions < T::Struct
85
- prop :disable_log_exposure, T::Boolean, default: false
87
+ class GetConfigOptions
88
+ attr_accessor :disable_log_exposure, :disable_evaluation_details
89
+
90
+ def initialize(disable_log_exposure: false, disable_evaluation_details: false)
91
+ @disable_log_exposure = disable_log_exposure
92
+ @disable_evaluation_details = disable_evaluation_details
93
+ end
86
94
  end
87
95
 
88
- sig { params(user: StatsigUser, dynamic_config_name: String, options: GetConfigOptions).returns(DynamicConfig) }
89
96
  ##
90
97
  # Get the values of a dynamic config, evaluated against the given user. An exposure event will automatically be logged for the dynamic config.
91
98
  #
92
- # @param user A StatsigUser object used for the evaluation
93
- # @param dynamic_config_name The name of the dynamic config
94
- # @param options Additional options for evaluating the config
95
- def self.get_config(user, dynamic_config_name, options = GetConfigOptions.new)
99
+ # @param [StatsigUser] user A StatsigUser object used for the evaluation
100
+ # @param [String] dynamic_config_name The name of the dynamic config
101
+ # @param [GetConfigOptions] options Additional options for evaluating the config
102
+ # @return [DynamicConfig]
103
+ def self.get_config(user, dynamic_config_name, options = nil)
96
104
  ensure_initialized
97
105
  @shared_instance&.get_config(user, dynamic_config_name, options)
98
106
  end
99
107
 
100
- sig { params(user: StatsigUser, dynamic_config_name: String).returns(DynamicConfig) }
101
108
  ##
109
+ # @deprecated - use get_config(user, config, options) and disable_exposure_logging in options
102
110
  # Get the values of a dynamic config, evaluated against the given user.
103
111
  #
104
- # @param user A StatsigUser object used for the evaluation
105
- # @param dynamic_config_name The name of the dynamic config
112
+ # @param [StatsigUser] user A StatsigUser object used for the evaluation
113
+ # @param [String] dynamic_config_name The name of the dynamic config
114
+ # @return [DynamicConfig]
106
115
  def self.get_config_with_exposure_logging_disabled(user, dynamic_config_name)
107
116
  ensure_initialized
108
117
  @shared_instance&.get_config(user, dynamic_config_name, GetConfigOptions.new(disable_log_exposure: true))
109
118
  end
110
119
 
111
- sig { params(user: StatsigUser, dynamic_config: String).void }
112
120
  ##
113
121
  # Logs an exposure event for the dynamic config
114
122
  #
@@ -119,35 +127,38 @@ module Statsig
119
127
  @shared_instance&.manually_log_config_exposure(user, dynamic_config)
120
128
  end
121
129
 
122
- class GetExperimentOptions < T::Struct
123
- prop :disable_log_exposure, T::Boolean, default: false
124
- prop :user_persisted_values, T.nilable(T::Hash[String, Hash]), default: nil
130
+ class GetExperimentOptions
131
+ attr_accessor :disable_log_exposure, :user_persisted_values, :disable_evaluation_details
132
+
133
+ def initialize(disable_log_exposure: false, user_persisted_values: nil, disable_evaluation_details: false)
134
+ @disable_log_exposure = disable_log_exposure
135
+ @user_persisted_values = user_persisted_values
136
+ @disable_evaluation_details = disable_evaluation_details
137
+ end
125
138
  end
126
139
 
127
- sig { params(user: StatsigUser, experiment_name: String, options: GetExperimentOptions).returns(DynamicConfig) }
128
140
  ##
129
141
  # Get the values of an experiment, evaluated against the given user. An exposure event will automatically be logged for the experiment.
130
142
  #
131
- # @param user A StatsigUser object used for the evaluation
132
- # @param experiment_name The name of the experiment
133
- # @param options Additional options for evaluating the experiment
134
- def self.get_experiment(user, experiment_name, options = GetExperimentOptions.new)
143
+ # @param [StatsigUser] user A StatsigUser object used for the evaluation
144
+ # @param [String] experiment_name The name of the experiment
145
+ # @param [GetExperimentOptions] options Additional options for evaluating the experiment
146
+ def self.get_experiment(user, experiment_name, options = nil)
135
147
  ensure_initialized
136
148
  @shared_instance&.get_experiment(user, experiment_name, options)
137
149
  end
138
150
 
139
- sig { params(user: StatsigUser, experiment_name: String).returns(DynamicConfig) }
140
151
  ##
152
+ # @deprecated - use get_experiment(user, experiment, options) and disable_exposure_logging in options
141
153
  # Get the values of an experiment, evaluated against the given user.
142
154
  #
143
- # @param user A StatsigUser object used for the evaluation
144
- # @param experiment_name The name of the experiment
155
+ # @param [StatsigUser] user A StatsigUser object used for the evaluation
156
+ # @param [String] experiment_name The name of the experiment
145
157
  def self.get_experiment_with_exposure_logging_disabled(user, experiment_name)
146
158
  ensure_initialized
147
159
  @shared_instance&.get_experiment(user, experiment_name, GetExperimentOptions.new(disable_log_exposure: true))
148
160
  end
149
161
 
150
- sig { params(user: StatsigUser, experiment_name: String).void }
151
162
  ##
152
163
  # Logs an exposure event for the experiment
153
164
  #
@@ -158,30 +169,34 @@ module Statsig
158
169
  @shared_instance&.manually_log_config_exposure(user, experiment_name)
159
170
  end
160
171
 
161
- sig { params(user: StatsigUser, id_type: String).returns(UserPersistedValues) }
162
172
  def self.get_user_persisted_values(user, id_type)
163
173
  ensure_initialized
164
174
  @shared_instance&.get_user_persisted_values(user, id_type)
165
175
  end
166
176
 
167
- class GetLayerOptions < T::Struct
168
- prop :disable_log_exposure, T::Boolean, default: false
177
+ class GetLayerOptions
178
+ attr_accessor :disable_log_exposure, :disable_evaluation_details
179
+
180
+ def initialize(disable_log_exposure: false, disable_evaluation_details: false)
181
+ @disable_log_exposure = disable_log_exposure
182
+ @disable_evaluation_details = disable_evaluation_details
183
+ end
169
184
  end
170
185
 
171
- sig { params(user: StatsigUser, layer_name: String, options: GetLayerOptions).returns(Layer) }
172
186
  ##
173
187
  # Get the values of a layer, evaluated against the given user.
174
188
  # Exposure events will be fired when get or get_typed is called on the resulting Layer class.
175
189
  #
176
- # @param user A StatsigUser object used for the evaluation
177
- # @param layer_name The name of the layer
178
- def self.get_layer(user, layer_name, options = GetLayerOptions.new)
190
+ # @param [StatsigUser] user A StatsigUser object used for the evaluation
191
+ # @param [String] layer_name The name of the layer
192
+ # @param [GetLayerOptions] options Configuration of how this method call should behave
193
+ def self.get_layer(user, layer_name, options = nil)
179
194
  ensure_initialized
180
195
  @shared_instance&.get_layer(user, layer_name, options)
181
196
  end
182
197
 
183
- sig { params(user: StatsigUser, layer_name: String).returns(Layer) }
184
198
  ##
199
+ # @deprecated - use get_layer(user, gate, options) and disable_exposure_logging in options
185
200
  # Get the values of a layer, evaluated against the given user.
186
201
  #
187
202
  # @param user A StatsigUser object used for the evaluation
@@ -191,7 +206,6 @@ module Statsig
191
206
  @shared_instance&.get_layer(user, layer_name, GetLayerOptions.new(disable_log_exposure: true))
192
207
  end
193
208
 
194
- sig { params(user: StatsigUser, layer_name: String, parameter_name: String).void }
195
209
  ##
196
210
  # Logs an exposure event for the parameter in the given layer
197
211
  #
@@ -203,10 +217,6 @@ module Statsig
203
217
  @shared_instance&.manually_log_layer_parameter_exposure(user, layer_name, parameter_name)
204
218
  end
205
219
 
206
- sig { params(user: StatsigUser,
207
- event_name: String,
208
- value: T.any(String, Integer, Float, NilClass),
209
- metadata: T.any(T::Hash[String, T.untyped], NilClass)).void }
210
220
  ##
211
221
  # Logs an event to Statsig with the provided values.
212
222
  #
@@ -229,7 +239,6 @@ module Statsig
229
239
  @shared_instance&.manually_sync_idlists
230
240
  end
231
241
 
232
- sig { returns(T::Array[String]) }
233
242
  ##
234
243
  # Returns a list of all gate names
235
244
  #
@@ -238,7 +247,6 @@ module Statsig
238
247
  @shared_instance&.list_gates
239
248
  end
240
249
 
241
- sig { returns(T::Array[String]) }
242
250
  ##
243
251
  # Returns a list of all config names
244
252
  #
@@ -247,7 +255,6 @@ module Statsig
247
255
  @shared_instance&.list_configs
248
256
  end
249
257
 
250
- sig { returns(T::Array[String]) }
251
258
  ##
252
259
  # Returns a list of all experiment names
253
260
  #
@@ -256,7 +263,6 @@ module Statsig
256
263
  @shared_instance&.list_experiments
257
264
  end
258
265
 
259
- sig { returns(T::Array[String]) }
260
266
  ##
261
267
  # Returns a list of all autotune names
262
268
  #
@@ -265,7 +271,6 @@ module Statsig
265
271
  @shared_instance&.list_autotunes
266
272
  end
267
273
 
268
- sig { returns(T::Array[String]) }
269
274
  ##
270
275
  # Returns a list of all layer names
271
276
  #
@@ -274,7 +279,6 @@ module Statsig
274
279
  @shared_instance&.list_layers
275
280
  end
276
281
 
277
- sig { void }
278
282
  ##
279
283
  # Stops all Statsig activity and flushes any pending events.
280
284
  def self.shutdown
@@ -284,7 +288,6 @@ module Statsig
284
288
  @shared_instance = nil
285
289
  end
286
290
 
287
- sig { params(gate_name: String, gate_value: T::Boolean).void }
288
291
  ##
289
292
  # Sets a value to be returned for the given gate instead of the actual evaluated value.
290
293
  #
@@ -295,7 +298,6 @@ module Statsig
295
298
  @shared_instance&.override_gate(gate_name, gate_value)
296
299
  end
297
300
 
298
- sig { params(config_name: String, config_value: Hash).void }
299
301
  ##
300
302
  # Sets a value to be returned for the given dynamic config/experiment instead of the actual evaluated value.
301
303
  #
@@ -306,7 +308,6 @@ module Statsig
306
308
  @shared_instance&.override_config(config_name, config_value)
307
309
  end
308
310
 
309
- sig { params(user: StatsigUser, hash: String, client_sdk_key: T.any(String, NilClass)).returns(T.any(T::Hash[String, T.untyped], NilClass)) }
310
311
  ##
311
312
  # Gets all evaluated values for the given user.
312
313
  # These values can then be given to a Statsig Client SDK via bootstrapping.
@@ -321,13 +322,12 @@ module Statsig
321
322
  @shared_instance&.get_client_initialize_response(user, hash, client_sdk_key)
322
323
  end
323
324
 
324
- sig { returns(T::Hash[String, String]) }
325
325
  ##
326
326
  # Internal Statsig metadata for this SDK
327
327
  def self.get_statsig_metadata
328
328
  {
329
329
  'sdkType' => 'ruby-server',
330
- 'sdkVersion' => '1.31.1',
330
+ 'sdkVersion' => '1.32.0',
331
331
  'languageVersion' => RUBY_VERSION
332
332
  }
333
333
  end
@@ -340,29 +340,4 @@ module Statsig
340
340
  end
341
341
  end
342
342
 
343
- sig { params(options: T.any(StatsigOptions, NilClass)).void }
344
- def self.bind_sorbet_loggers(options)
345
- if options&.disable_sorbet_logging_handlers == true
346
- return
347
- end
348
-
349
- T::Configuration.call_validation_error_handler = lambda do |signature, opts|
350
- puts "[Type Error] " + opts[:pretty_message]
351
- end
352
-
353
- T::Configuration.inline_type_error_handler = lambda do |error, opts|
354
- puts "[Type Error] " + error.message
355
- end
356
-
357
- T::Configuration.sig_builder_error_handler = lambda do |error, location|
358
- puts "[Type Error] " + error.message
359
- end
360
-
361
- T::Configuration.sig_validation_error_handler = lambda do |error, opts|
362
- puts "[Type Error] " + error.message
363
- end
364
-
365
- return
366
- end
367
-
368
- end
343
+ end
@@ -1,5 +1,3 @@
1
- # typed: true
2
-
3
1
  require 'config_result'
4
2
  require 'evaluator'
5
3
  require 'network'
@@ -13,13 +11,11 @@ require 'dynamic_config'
13
11
  require 'feature_gate'
14
12
  require 'error_boundary'
15
13
  require 'layer'
16
- require 'sorbet-runtime'
14
+
17
15
  require 'diagnostics'
18
16
 
19
17
  class StatsigDriver
20
- extend T::Sig
21
18
 
22
- sig { params(secret_key: String, options: T.any(StatsigOptions, NilClass), error_callback: T.any(Method, Proc, NilClass)).void }
23
19
  def initialize(secret_key, options = nil, error_callback = nil)
24
20
  unless secret_key.start_with?('secret-')
25
21
  raise Statsig::ValueError.new('Invalid secret key provided. Provide your project secret key from the Statsig console')
@@ -47,26 +43,16 @@ class StatsigDriver
47
43
  }, caller: __method__.to_s)
48
44
  end
49
45
 
50
- sig do
51
- params(
52
- user: StatsigUser,
53
- gate_name: String,
54
- disable_log_exposure: T::Boolean,
55
- skip_evaluation: T::Boolean
56
- ).returns(FeatureGate)
57
- end
58
- def get_gate_impl(user, gate_name, disable_log_exposure: false, skip_evaluation: false)
46
+ def get_gate_impl(user, gate_name, disable_log_exposure: false, skip_evaluation: false, disable_evaluation_details: false)
59
47
  if skip_evaluation
60
48
  gate = @store.get_gate(gate_name)
61
49
  return FeatureGate.new(gate_name) if gate.nil?
62
- return FeatureGate.new(gate['name'], target_app_ids: gate['targetAppIDs'])
50
+ return FeatureGate.new(gate.name, target_app_ids: gate.target_app_ids)
63
51
  end
64
52
  user = verify_inputs(user, gate_name, 'gate_name')
65
53
 
66
- res = @evaluator.check_gate(user, gate_name)
67
- if res.nil?
68
- res = Statsig::ConfigResult.new(gate_name)
69
- end
54
+ res = Statsig::ConfigResult.new(name: gate_name, disable_exposures: disable_log_exposure, disable_evaluation_details: disable_evaluation_details)
55
+ @evaluator.check_gate(user, gate_name, res)
70
56
 
71
57
  unless disable_log_exposure
72
58
  @logger.log_gate_exposure(
@@ -76,63 +62,79 @@ class StatsigDriver
76
62
  FeatureGate.from_config_result(res)
77
63
  end
78
64
 
79
- sig { params(user: StatsigUser, gate_name: String, options: Statsig::GetGateOptions).returns(FeatureGate) }
80
- def get_gate(user, gate_name, options = Statsig::GetGateOptions.new)
65
+ def get_gate(user, gate_name, options = nil)
81
66
  @err_boundary.capture(task: lambda {
82
67
  run_with_diagnostics(task: lambda {
83
- get_gate_impl(user, gate_name, disable_log_exposure: options.disable_log_exposure, skip_evaluation: options.skip_evaluation)
68
+ get_gate_impl(user, gate_name,
69
+ disable_log_exposure: options&.disable_log_exposure == true,
70
+ skip_evaluation: options&.skip_evaluation == true,
71
+ disable_evaluation_details: options&.disable_evaluation_details == true
72
+ )
84
73
  }, caller: __method__.to_s)
85
74
  }, recover: -> { false }, caller: __method__.to_s)
86
75
  end
87
76
 
88
- sig { params(user: StatsigUser, gate_name: String, options: Statsig::CheckGateOptions).returns(T::Boolean) }
89
- def check_gate(user, gate_name, options = Statsig::CheckGateOptions.new)
77
+ def check_gate(user, gate_name, options = nil)
90
78
  @err_boundary.capture(task: lambda {
91
79
  run_with_diagnostics(task: lambda {
92
- get_gate_impl(user, gate_name, disable_log_exposure: options.disable_log_exposure).value
80
+ get_gate_impl(
81
+ user,
82
+ gate_name,
83
+ disable_log_exposure: options&.disable_log_exposure == true,
84
+ disable_evaluation_details: options&.disable_evaluation_details == true
85
+ ).value
93
86
  }, caller: __method__.to_s)
94
87
  }, recover: -> { false }, caller: __method__.to_s)
95
88
  end
96
89
 
97
- sig { params(user: StatsigUser, gate_name: String).void }
98
90
  def manually_log_gate_exposure(user, gate_name)
99
91
  @err_boundary.capture(task: lambda {
100
- res = @evaluator.check_gate(user, gate_name)
101
- context = { 'is_manual_exposure' => true }
92
+ res = Statsig::ConfigResult.new(name: gate_name)
93
+ @evaluator.check_gate(user, gate_name, res)
94
+ context = { :is_manual_exposure => true }
102
95
  @logger.log_gate_exposure(user, gate_name, res.gate_value, res.rule_id, res.secondary_exposures, res.evaluation_details, context)
103
96
  })
104
97
  end
105
98
 
106
- sig { params(user: StatsigUser, dynamic_config_name: String, options: Statsig::GetConfigOptions).returns(DynamicConfig) }
107
- def get_config(user, dynamic_config_name, options = Statsig::GetConfigOptions.new)
99
+ def get_config(user, dynamic_config_name, options = nil)
108
100
  @err_boundary.capture(task: lambda {
109
101
  run_with_diagnostics(task: lambda {
110
102
  user = verify_inputs(user, dynamic_config_name, "dynamic_config_name")
111
- get_config_impl(user, dynamic_config_name, options.disable_log_exposure)
103
+ get_config_impl(
104
+ user,
105
+ dynamic_config_name,
106
+ options&.disable_log_exposure == true,
107
+ disable_evaluation_details: options&.disable_evaluation_details == true
108
+ )
112
109
  }, caller: __method__.to_s)
113
110
  }, recover: -> { DynamicConfig.new(dynamic_config_name) }, caller: __method__.to_s)
114
111
  end
115
112
 
116
- sig { params(user: StatsigUser, experiment_name: String, options: Statsig::GetExperimentOptions).returns(DynamicConfig) }
117
- def get_experiment(user, experiment_name, options = Statsig::GetExperimentOptions.new)
113
+ def get_experiment(user, experiment_name, options = nil)
118
114
  @err_boundary.capture(task: lambda {
119
115
  run_with_diagnostics(task: lambda {
120
116
  user = verify_inputs(user, experiment_name, "experiment_name")
121
- get_config_impl(user, experiment_name, options.disable_log_exposure, user_persisted_values: options.user_persisted_values)
117
+ get_config_impl(
118
+ user,
119
+ experiment_name,
120
+ options&.disable_log_exposure == true,
121
+ user_persisted_values: options&.user_persisted_values,
122
+ disable_evaluation_details: options&.disable_evaluation_details == true
123
+ )
122
124
  }, caller: __method__.to_s)
123
125
  }, recover: -> { DynamicConfig.new(experiment_name) }, caller: __method__.to_s)
124
126
  end
125
127
 
126
- sig { params(user: StatsigUser, config_name: String).void }
127
128
  def manually_log_config_exposure(user, config_name)
128
129
  @err_boundary.capture(task: lambda {
129
- res = @evaluator.get_config(user, config_name)
130
- context = { 'is_manual_exposure' => true }
130
+ res = Statsig::ConfigResult.new(name: config_name)
131
+ @evaluator.get_config(user, config_name, res)
132
+
133
+ context = { :is_manual_exposure => true }
131
134
  @logger.log_config_exposure(user, res.name, res.rule_id, res.secondary_exposures, res.evaluation_details, context)
132
135
  }, caller: __method__.to_s)
133
136
  end
134
137
 
135
- sig { params(user: StatsigUser, id_type: String).returns(Statsig::UserPersistedValues) }
136
138
  def get_user_persisted_values(user, id_type)
137
139
  @err_boundary.capture(task: lambda {
138
140
  persisted_values = @persistent_storage_utils.get_user_persisted_values(user, id_type)
@@ -142,31 +144,34 @@ class StatsigDriver
142
144
  }, caller: __method__.to_s)
143
145
  end
144
146
 
145
- sig { params(user: StatsigUser, layer_name: String, options: Statsig::GetLayerOptions).returns(Layer) }
146
- def get_layer(user, layer_name, options = Statsig::GetLayerOptions.new)
147
+ def get_layer(user, layer_name, options = nil)
147
148
  @err_boundary.capture(task: lambda {
148
149
  run_with_diagnostics(task: lambda {
149
150
  user = verify_inputs(user, layer_name, "layer_name")
150
-
151
- res = @evaluator.get_layer(user, layer_name)
152
- if res.nil?
153
- res = Statsig::ConfigResult.new(layer_name)
154
- end
155
-
156
- exposure_log_func = !options.disable_log_exposure ? lambda { |layer, parameter_name|
151
+ exposures_disabled = options&.disable_log_exposure == true
152
+ res = Statsig::ConfigResult.new(
153
+ name: layer_name,
154
+ disable_exposures: exposures_disabled,
155
+ disable_evaluation_details: options&.disable_evaluation_details == true
156
+ )
157
+ @evaluator.get_layer(user, layer_name, res)
158
+
159
+ exposure_log_func = !exposures_disabled ? lambda { |layer, parameter_name|
157
160
  @logger.log_layer_exposure(user, layer, parameter_name, res)
158
161
  } : nil
162
+
159
163
  Layer.new(res.name, res.json_value, res.rule_id, res.group_name, res.config_delegate, exposure_log_func)
160
164
  }, caller: __method__.to_s)
161
165
  }, recover: lambda { Layer.new(layer_name) }, caller: __method__.to_s)
162
166
  end
163
167
 
164
- sig { params(user: StatsigUser, layer_name: String, parameter_name: String).void }
165
168
  def manually_log_layer_parameter_exposure(user, layer_name, parameter_name)
166
169
  @err_boundary.capture(task: lambda {
167
- res = @evaluator.get_layer(user, layer_name)
170
+ res = Statsig::ConfigResult.new(name: layer_name)
171
+ @evaluator.get_layer(user, layer_name, res)
172
+
168
173
  layer = Layer.new(layer_name, res.json_value, res.rule_id, res.group_name, res.config_delegate)
169
- context = { 'is_manual_exposure' => true }
174
+ context = { :is_manual_exposure => true }
170
175
  @logger.log_layer_exposure(user, layer, parameter_name, res, context)
171
176
  }, caller: __method__.to_s)
172
177
  end
@@ -200,35 +205,30 @@ class StatsigDriver
200
205
  }, caller: __method__.to_s)
201
206
  end
202
207
 
203
- sig { returns(T::Array[String]) }
204
208
  def list_gates
205
209
  @err_boundary.capture(task: lambda {
206
210
  @evaluator.list_gates
207
211
  }, caller: __method__.to_s)
208
212
  end
209
213
 
210
- sig { returns(T::Array[String]) }
211
214
  def list_configs
212
215
  @err_boundary.capture(task: lambda {
213
216
  @evaluator.list_configs
214
217
  }, caller: __method__.to_s)
215
218
  end
216
219
 
217
- sig { returns(T::Array[String]) }
218
220
  def list_experiments
219
221
  @err_boundary.capture(task: lambda {
220
222
  @evaluator.list_experiments
221
223
  }, caller: __method__.to_s)
222
224
  end
223
225
 
224
- sig { returns(T::Array[String]) }
225
226
  def list_autotunes
226
227
  @err_boundary.capture(task: lambda {
227
228
  @evaluator.list_autotunes
228
229
  }, caller: __method__.to_s)
229
230
  end
230
231
 
231
- sig { returns(T::Array[String]) }
232
232
  def list_layers
233
233
  @err_boundary.capture(task: lambda {
234
234
  @evaluator.list_layers
@@ -297,7 +297,6 @@ class StatsigDriver
297
297
  return res
298
298
  end
299
299
 
300
- sig { params(user: StatsigUser, config_name: String, variable_name: String).returns(StatsigUser) }
301
300
  def verify_inputs(user, config_name, variable_name)
302
301
  validate_user(user)
303
302
  if !config_name.is_a?(String) || config_name.empty?
@@ -309,19 +308,13 @@ class StatsigDriver
309
308
  normalize_user(user)
310
309
  end
311
310
 
312
- sig do
313
- params(
314
- user: StatsigUser,
315
- config_name: String,
316
- disable_log_exposure: T::Boolean,
317
- user_persisted_values: T.nilable(Statsig::UserPersistedValues)
318
- ).returns(DynamicConfig)
319
- end
320
- def get_config_impl(user, config_name, disable_log_exposure, user_persisted_values: nil)
321
- res = @evaluator.get_config(user, config_name, user_persisted_values: user_persisted_values)
322
- if res.nil?
323
- res = Statsig::ConfigResult.new(config_name)
324
- end
311
+ def get_config_impl(user, config_name, disable_log_exposure, user_persisted_values: nil, disable_evaluation_details: false)
312
+ res = Statsig::ConfigResult.new(
313
+ name: config_name,
314
+ disable_exposures: disable_log_exposure,
315
+ disable_evaluation_details: disable_evaluation_details
316
+ )
317
+ @evaluator.get_config(user, config_name, res, user_persisted_values: user_persisted_values)
325
318
 
326
319
  unless disable_log_exposure
327
320
  @logger.log_config_exposure(user, res.name, res.rule_id, res.secondary_exposures, res.evaluation_details)
@@ -343,7 +336,7 @@ class StatsigDriver
343
336
  end
344
337
 
345
338
  def normalize_user(user)
346
- if user.statsig_environment.nil? && !@options&.environment.nil?
339
+ if !@options&.environment.nil?
347
340
  user.statsig_environment = @options.environment
348
341
  end
349
342
  user
@@ -1,4 +1,4 @@
1
- # typed: true
1
+
2
2
  module Statsig
3
3
  class UninitializedError < StandardError
4
4
  def initialize(msg="Must call initialize first.")
data/lib/statsig_event.rb CHANGED
@@ -1,4 +1,4 @@
1
- # typed: true
1
+
2
2
  class StatsigEvent
3
3
  attr_accessor :value, :metadata, :statsig_metadata, :secondary_exposures
4
4
  attr_reader :user
@@ -21,13 +21,13 @@ class StatsigEvent
21
21
 
22
22
  def serialize
23
23
  {
24
- 'eventName' => @event_name,
25
- 'metadata' => @metadata,
26
- 'value' => @value,
27
- 'user' => @user,
28
- 'time' => @time,
29
- 'statsigMetadata' => @statsig_metadata,
30
- 'secondaryExposures' => @secondary_exposures
24
+ :eventName => @event_name,
25
+ :metadata => @metadata,
26
+ :value => @value,
27
+ :user => @user,
28
+ :time => @time,
29
+ :statsigMetadata => @statsig_metadata,
30
+ :secondaryExposures => @secondary_exposures
31
31
  }
32
32
  end
33
33
  end