statsig 1.31.1 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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