statsig 2.0.0 → 2.1.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.
- checksums.yaml +4 -4
- data/lib/client_initialize_helpers.rb +16 -2
- data/lib/constants.rb +6 -0
- data/lib/dynamic_config.rb +14 -2
- data/lib/evaluation_helpers.rb +13 -1
- data/lib/evaluator.rb +24 -2
- data/lib/layer.rb +23 -4
- data/lib/statsig.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd554df4ba15f0d1addaecc5e76502c1218c1b08842152eeeffd0f6e121dbcba
|
4
|
+
data.tar.gz: b1d19d91608685488db9705e213559c4a36c21731b0822137b55fab0693a871d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b360f7fb18b06e87b538eb005ce0f7344f8a633a1cb9915d3e6f74e5b0fab3b7d87d46ab4b4498548e66766d00a4f60a9bb5f502c270e09925e67c24575da7ca
|
7
|
+
data.tar.gz: 337e0fd5ecfc11fa5565980df91d21ee17cc6586d49f1a18b333eaa4de1da29094c453a00daf1671ce8e6872d03882b85c169df6709aa41e543500cdc5c78057
|
@@ -92,12 +92,26 @@ module Statsig
|
|
92
92
|
result[:rule_id] = eval_result.rule_id
|
93
93
|
|
94
94
|
if include_exposures
|
95
|
-
result[:secondary_exposures] = eval_result.secondary_exposures
|
95
|
+
result[:secondary_exposures] = hash_exposures(eval_result.secondary_exposures, hash_algo)
|
96
96
|
end
|
97
97
|
|
98
98
|
[hashed_name, result]
|
99
99
|
end
|
100
100
|
|
101
|
+
def self.hash_exposures(exposures, hash_algo)
|
102
|
+
return nil if exposures.nil?
|
103
|
+
hashed_exposures = []
|
104
|
+
exposures.each do |exp|
|
105
|
+
hashed_exposures << {
|
106
|
+
gate: hash_name(exp[:gate], hash_algo),
|
107
|
+
gateValue: exp[:gateValue],
|
108
|
+
ruleID: exp[:ruleID]
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
hashed_exposures
|
113
|
+
end
|
114
|
+
|
101
115
|
def self.populate_experiment_fields(config_name, config_spec, eval_result, result, evaluator)
|
102
116
|
result[:is_user_in_experiment] = eval_result.is_experiment_group
|
103
117
|
result[:is_experiment_active] = config_spec[:isActive] == true
|
@@ -132,7 +146,7 @@ module Statsig
|
|
132
146
|
end
|
133
147
|
|
134
148
|
if include_exposures
|
135
|
-
result[:undelegated_secondary_exposures] = eval_result.undelegated_sec_exps || []
|
149
|
+
result[:undelegated_secondary_exposures] = hash_exposures(eval_result.undelegated_sec_exps || [], hash_algo)
|
136
150
|
end
|
137
151
|
end
|
138
152
|
|
data/lib/constants.rb
CHANGED
@@ -123,5 +123,11 @@ module Statsig
|
|
123
123
|
# API Operators (Segments)
|
124
124
|
OP_IN_SEGMENT_LIST = 'in_segment_list'.freeze
|
125
125
|
OP_NOT_IN_SEGMENT_LIST = 'not_in_segment_list'.freeze
|
126
|
+
|
127
|
+
# API Operators (Array)
|
128
|
+
OP_ARRAY_CONTAINS_ANY = 'array_contains_any'.freeze
|
129
|
+
OP_ARRAY_CONTAINS_NONE = 'array_contains_none'.freeze
|
130
|
+
OP_ARRAY_CONTAINS_ALL = 'array_contains_all'.freeze
|
131
|
+
OP_NOT_ARRAY_CONTAINS_ALL = 'not_array_contains_all'.freeze
|
126
132
|
end
|
127
133
|
end
|
data/lib/dynamic_config.rb
CHANGED
@@ -53,7 +53,19 @@ class DynamicConfig
|
|
53
53
|
index_sym = index.to_sym
|
54
54
|
return default_value unless @value.key?(index_sym)
|
55
55
|
|
56
|
-
|
57
|
-
|
56
|
+
value = @value[index_sym]
|
57
|
+
|
58
|
+
case default_value
|
59
|
+
when Integer
|
60
|
+
return value.to_i if value.is_a?(Numeric) && default_value.is_a?(Integer)
|
61
|
+
when Float
|
62
|
+
return value.to_f if value.is_a?(Numeric) && default_value.is_a?(Float)
|
63
|
+
when TrueClass, FalseClass
|
64
|
+
return value if [true, false].include?(value)
|
65
|
+
else
|
66
|
+
return value if value.class == default_value.class
|
67
|
+
end
|
68
|
+
|
69
|
+
default_value
|
58
70
|
end
|
59
71
|
end
|
data/lib/evaluation_helpers.rb
CHANGED
@@ -58,6 +58,18 @@ module EvaluationHelpers
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
+
def self.array_contains_any(value, target)
|
62
|
+
return false if value.nil? || target.nil?
|
63
|
+
value_set = value.to_set
|
64
|
+
return target.any? { |item| value_set.include?(item) || value_set.include?(item.to_i) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.array_contains_all(value, target)
|
68
|
+
return false if value.nil? || target.nil?
|
69
|
+
value_set = value.to_set
|
70
|
+
return target.all? { |item| value_set.include?(item) || value_set.include?(item.to_i) }
|
71
|
+
end
|
72
|
+
|
61
73
|
private
|
62
74
|
|
63
75
|
def self.is_numeric(v)
|
@@ -73,4 +85,4 @@ module EvaluationHelpers
|
|
73
85
|
end
|
74
86
|
return time.to_i
|
75
87
|
end
|
76
|
-
end
|
88
|
+
end
|
data/lib/evaluator.rb
CHANGED
@@ -246,7 +246,7 @@ module Statsig
|
|
246
246
|
evaluated_keys: evaluated_keys,
|
247
247
|
time: @spec_store.last_config_sync_time,
|
248
248
|
hash_used: hash_algo,
|
249
|
-
user: user.serialize(
|
249
|
+
user: user.serialize(true),
|
250
250
|
sdkInfo: {sdkType: meta["sdkType"], sdkVersion: meta["sdkVersion"]},
|
251
251
|
}
|
252
252
|
end
|
@@ -542,6 +542,24 @@ module Statsig
|
|
542
542
|
a.year == b.year && a.month == b.month && a.day == b.day
|
543
543
|
})
|
544
544
|
|
545
|
+
# array
|
546
|
+
when Const::OP_ARRAY_CONTAINS_ANY
|
547
|
+
if value.is_a?(Array) && target.is_a?(Array)
|
548
|
+
return EvaluationHelpers.array_contains_any(value, target)
|
549
|
+
end
|
550
|
+
when Const::OP_ARRAY_CONTAINS_NONE
|
551
|
+
if value.is_a?(Array) && target.is_a?(Array)
|
552
|
+
return !EvaluationHelpers.array_contains_any(value, target)
|
553
|
+
end
|
554
|
+
when Const::OP_ARRAY_CONTAINS_ALL
|
555
|
+
if value.is_a?(Array) && target.is_a?(Array)
|
556
|
+
return EvaluationHelpers.array_contains_all(value, target)
|
557
|
+
end
|
558
|
+
when Const::OP_NOT_ARRAY_CONTAINS_ALL
|
559
|
+
if value.is_a?(Array) && target.is_a?(Array)
|
560
|
+
return !EvaluationHelpers.array_contains_all(value, target)
|
561
|
+
end
|
562
|
+
|
545
563
|
# segments
|
546
564
|
when Const::OP_IN_SEGMENT_LIST, Const::OP_NOT_IN_SEGMENT_LIST
|
547
565
|
begin
|
@@ -670,10 +688,14 @@ module Statsig
|
|
670
688
|
end
|
671
689
|
|
672
690
|
def eval_pass_percent(user, rule, config_salt)
|
691
|
+
pass_percentage = rule[:passPercentage]
|
692
|
+
return true if pass_percentage == 100.0
|
693
|
+
return false if pass_percentage == 0.0
|
694
|
+
|
673
695
|
unit_id = user.get_unit_id(rule[:idType]) || Const::EMPTY_STR
|
674
696
|
rule_salt = rule[:salt] || rule[:id] || Const::EMPTY_STR
|
675
697
|
hash = compute_user_hash("#{config_salt}.#{rule_salt}.#{unit_id}")
|
676
|
-
return (hash % 10_000) < (
|
698
|
+
return (hash % 10_000) < (pass_percentage * 100)
|
677
699
|
end
|
678
700
|
|
679
701
|
def compute_user_hash(user_hash)
|
data/lib/layer.rb
CHANGED
@@ -52,12 +52,31 @@ class Layer
|
|
52
52
|
index_sym = index.to_sym
|
53
53
|
return default_value unless @value.key?(index_sym)
|
54
54
|
|
55
|
-
|
55
|
+
value = @value[index_sym]
|
56
56
|
|
57
|
-
|
58
|
-
|
57
|
+
case default_value
|
58
|
+
when Integer
|
59
|
+
if @exposure_log_func.is_a? Proc
|
60
|
+
@exposure_log_func.call(self, index)
|
61
|
+
end
|
62
|
+
return value.to_i if value.is_a?(Numeric) && default_value.is_a?(Integer)
|
63
|
+
when Float
|
64
|
+
if @exposure_log_func.is_a? Proc
|
65
|
+
@exposure_log_func.call(self, index)
|
66
|
+
end
|
67
|
+
return value.to_f if value.is_a?(Numeric) && default_value.is_a?(Float)
|
68
|
+
when TrueClass, FalseClass
|
69
|
+
if @exposure_log_func.is_a? Proc
|
70
|
+
@exposure_log_func.call(self, index)
|
71
|
+
end
|
72
|
+
return value if [true, false].include?(value)
|
73
|
+
else
|
74
|
+
if @exposure_log_func.is_a? Proc
|
75
|
+
@exposure_log_func.call(self, index)
|
76
|
+
end
|
77
|
+
return value if value.class == default_value.class
|
59
78
|
end
|
60
79
|
|
61
|
-
|
80
|
+
default_value
|
62
81
|
end
|
63
82
|
end
|
data/lib/statsig.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: statsig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Statsig, Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|