statsig 1.30.0 → 1.32.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/api_config.rb +128 -0
- data/lib/client_initialize_helpers.rb +79 -108
- data/lib/config_result.rb +17 -32
- data/lib/constants.rb +60 -0
- data/lib/diagnostics.rb +21 -70
- data/lib/dynamic_config.rb +1 -24
- data/lib/error_boundary.rb +0 -5
- data/lib/evaluation_details.rb +5 -1
- data/lib/evaluation_helpers.rb +35 -3
- data/lib/evaluator.rb +332 -316
- data/lib/feature_gate.rb +0 -24
- data/lib/id_list.rb +1 -1
- data/lib/interfaces/data_store.rb +1 -1
- data/lib/interfaces/user_persistent_storage.rb +1 -1
- data/lib/layer.rb +1 -20
- data/lib/network.rb +6 -53
- data/lib/spec_store.rb +124 -115
- data/lib/statsig.rb +72 -97
- data/lib/statsig_driver.rb +73 -128
- data/lib/statsig_errors.rb +1 -1
- data/lib/statsig_event.rb +8 -8
- data/lib/statsig_logger.rb +29 -26
- data/lib/statsig_options.rb +0 -50
- data/lib/statsig_user.rb +27 -68
- data/lib/ua_parser.rb +1 -1
- data/lib/uri_helper.rb +1 -9
- data/lib/user_persistent_storage_utils.rb +0 -17
- metadata +4 -2
data/lib/dynamic_config.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
# typed: false
|
2
|
-
|
3
|
-
require 'sorbet-runtime'
|
4
|
-
|
5
1
|
##
|
6
2
|
# Contains the current experiment/dynamic config values from Statsig
|
7
3
|
#
|
@@ -9,46 +5,28 @@ require 'sorbet-runtime'
|
|
9
5
|
#
|
10
6
|
# Experiments Documentation: https://docs.statsig.com/experiments-plus
|
11
7
|
class DynamicConfig
|
12
|
-
extend T::Sig
|
13
8
|
|
14
|
-
sig { returns(String) }
|
15
9
|
attr_accessor :name
|
16
10
|
|
17
|
-
sig { returns(T::Hash[String, T.untyped]) }
|
18
11
|
attr_accessor :value
|
19
12
|
|
20
|
-
sig { returns(String) }
|
21
13
|
attr_accessor :rule_id
|
22
14
|
|
23
|
-
sig { returns(T.nilable(String)) }
|
24
15
|
attr_accessor :group_name
|
25
16
|
|
26
|
-
sig { returns(String) }
|
27
17
|
attr_accessor :id_type
|
28
18
|
|
29
|
-
sig { returns(T.nilable(Statsig::EvaluationDetails)) }
|
30
19
|
attr_accessor :evaluation_details
|
31
20
|
|
32
|
-
sig do
|
33
|
-
params(
|
34
|
-
name: String,
|
35
|
-
value: T::Hash[String, T.untyped],
|
36
|
-
rule_id: String,
|
37
|
-
group_name: T.nilable(String),
|
38
|
-
id_type: String,
|
39
|
-
evaluation_details: T.nilable(Statsig::EvaluationDetails)
|
40
|
-
).void
|
41
|
-
end
|
42
21
|
def initialize(name, value = {}, rule_id = '', group_name = nil, id_type = '', evaluation_details = nil)
|
43
22
|
@name = name
|
44
|
-
@value = value
|
23
|
+
@value = value || {}
|
45
24
|
@rule_id = rule_id
|
46
25
|
@group_name = group_name
|
47
26
|
@id_type = id_type
|
48
27
|
@evaluation_details = evaluation_details
|
49
28
|
end
|
50
29
|
|
51
|
-
sig { params(index: String, default_value: T.untyped).returns(T.untyped) }
|
52
30
|
##
|
53
31
|
# Get the value for the given key (index), falling back to the default_value if it cannot be found.
|
54
32
|
#
|
@@ -59,7 +37,6 @@ class DynamicConfig
|
|
59
37
|
@value[index]
|
60
38
|
end
|
61
39
|
|
62
|
-
sig { params(index: String, default_value: T.untyped).returns(T.untyped) }
|
63
40
|
##
|
64
41
|
# Get the value for the given key (index), falling back to the default_value if it cannot be found
|
65
42
|
# or is found to have a different type from the default_value.
|
data/lib/error_boundary.rb
CHANGED
@@ -1,15 +1,10 @@
|
|
1
|
-
# typed: true
|
2
|
-
|
3
1
|
require 'statsig_errors'
|
4
|
-
require 'sorbet-runtime'
|
5
2
|
|
6
3
|
$endpoint = 'https://statsigapi.net/v1/sdk_exception'
|
7
4
|
|
8
5
|
module Statsig
|
9
6
|
class ErrorBoundary
|
10
|
-
extend T::Sig
|
11
7
|
|
12
|
-
sig { params(sdk_key: String).void }
|
13
8
|
def initialize(sdk_key)
|
14
9
|
@sdk_key = sdk_key
|
15
10
|
@seen = Set.new
|
data/lib/evaluation_details.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# typed: true
|
2
1
|
module Statsig
|
3
2
|
|
4
3
|
module EvaluationReason
|
@@ -9,6 +8,7 @@ module Statsig
|
|
9
8
|
BOOTSTRAP = 'Bootstrap'.freeze
|
10
9
|
DATA_ADAPTER = 'DataAdapter'.freeze
|
11
10
|
PERSISTED = 'Persisted'.freeze
|
11
|
+
UNSUPPORTED = 'Unsupported'.freeze
|
12
12
|
end
|
13
13
|
|
14
14
|
class EvaluationDetails
|
@@ -24,6 +24,10 @@ module Statsig
|
|
24
24
|
@server_time = (Time.now.to_i * 1000).to_s
|
25
25
|
end
|
26
26
|
|
27
|
+
def self.unsupported(config_sync_time, init_time)
|
28
|
+
EvaluationDetails.new(config_sync_time, init_time, EvaluationReason::UNSUPPORTED)
|
29
|
+
end
|
30
|
+
|
27
31
|
def self.unrecognized(config_sync_time, init_time)
|
28
32
|
EvaluationDetails.new(config_sync_time, init_time, EvaluationReason::UNRECOGNIZED)
|
29
33
|
end
|
data/lib/evaluation_helpers.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# typed: true
|
2
1
|
require 'time'
|
3
2
|
|
4
3
|
module EvaluationHelpers
|
@@ -9,9 +8,41 @@ module EvaluationHelpers
|
|
9
8
|
|
10
9
|
# returns true if array has any element that evaluates to true with value using func lambda, ignoring case
|
11
10
|
def self.match_string_in_array(array, value, ignore_case, func)
|
12
|
-
return false unless array.is_a?(Array) && !value.nil?
|
13
11
|
str_value = value.to_s
|
14
|
-
|
12
|
+
str_value_downcased = nil
|
13
|
+
|
14
|
+
return false if array.nil?
|
15
|
+
|
16
|
+
return array.any? do |item|
|
17
|
+
next false if item.nil?
|
18
|
+
item_str = item.to_s
|
19
|
+
|
20
|
+
return true if func.call(str_value, item_str)
|
21
|
+
next false unless ignore_case
|
22
|
+
|
23
|
+
str_value_downcased ||= str_value.downcase
|
24
|
+
func.call(str_value_downcased, item_str.downcase)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.equal_string_in_array(array, value, ignore_case)
|
29
|
+
str_value = value.to_s
|
30
|
+
str_value_downcased = nil
|
31
|
+
|
32
|
+
return false if array.nil?
|
33
|
+
|
34
|
+
return array.any? do |item|
|
35
|
+
next false if item.nil?
|
36
|
+
item_str = item.to_s
|
37
|
+
|
38
|
+
next false unless item_str.length == str_value.length
|
39
|
+
|
40
|
+
return true if item_str == str_value
|
41
|
+
next false unless ignore_case
|
42
|
+
|
43
|
+
str_value_downcased ||= str_value.downcase
|
44
|
+
item_str.downcase == str_value_downcased
|
45
|
+
end
|
15
46
|
end
|
16
47
|
|
17
48
|
def self.compare_times(a, b, func)
|
@@ -27,6 +58,7 @@ module EvaluationHelpers
|
|
27
58
|
private
|
28
59
|
|
29
60
|
def self.is_numeric(v)
|
61
|
+
return true if v.is_a?(Numeric)
|
30
62
|
!(v.to_s =~ /\A[-+]?\d*\.?\d+\z/).nil?
|
31
63
|
end
|
32
64
|
|