fino 1.3.1 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c47c47b3ab49c1eac2959185f67a6cc62e952936c7693f1e1d3d95843afaae88
4
- data.tar.gz: da1f3fea78b8d9adbf58a3209c87e6c8acd717371dafe7618f9a2522e744fc0d
3
+ metadata.gz: ee8bdd56792ffd6eed11da668a8df8785c85cc59d1bad28789131be52b7d4fe3
4
+ data.tar.gz: b3d2732be842a1f04dde6faa88c89c43a39198d017e94fc8939aa3a6bec09d5a
5
5
  SHA512:
6
- metadata.gz: bbadb8e1f7f954e7c1f0d9d1a0d7f6455236e67c6dfdaad87a02b9659b3a130f4c7be93cad53f9c486fad6cecd335a308e696ee82b91b1404f2a7fa31048c15c
7
- data.tar.gz: '0797cdb045a602b6f9b79ce8f772f7085c857d9addb3d664d74f3a3790676afe046b4c5d81ad4d6b2865b4c244b6debc7bc2ac6ed87cb255adf66fea4a57d9be'
6
+ metadata.gz: 6a24212d5ee902d515e6566a83473e4e2a980b0dc294da36071d5b6effb8c82acf3f3836c6beefce4880dc64ff43b4df56a53e366cb9c685ffdddc0c61f26f46
7
+ data.tar.gz: 27b249d2c12c74192af82b6260335044bb2fa89cd8d97d033bd4838b372c0b5e9e5c0a989544a442e7b44fda957b3925f0ed82c0317fed458a3115daa024bd9b
data/lib/fino/adapter.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fino::Adapter
4
- def read(setting_definition)
4
+ def read(setting_key)
5
5
  raise NotImplementedError
6
6
  end
7
7
 
8
- def read_multi(setting_definitions)
8
+ def read_multi(setting_keys)
9
9
  raise NotImplementedError
10
10
  end
11
11
 
@@ -13,6 +13,10 @@ module Fino::Adapter
13
13
  raise NotImplementedError
14
14
  end
15
15
 
16
+ def read_persisted_setting_keys
17
+ raise NotImplementedError
18
+ end
19
+
16
20
  def fetch_value_from(raw_adapter_data)
17
21
  raise NotImplementedError
18
22
  end
data/lib/fino/library.rb CHANGED
@@ -81,6 +81,10 @@ class Fino::Library
81
81
  pipeline.read_multi(setting_definitions)
82
82
  end
83
83
 
84
+ def persisted_keys
85
+ adapter.read_persisted_setting_keys
86
+ end
87
+
84
88
  private
85
89
 
86
90
  attr_reader :configuration
@@ -97,7 +101,11 @@ class Fino::Library
97
101
  end
98
102
 
99
103
  def storage
100
- Fino::Pipe::Storage.new(configuration.adapter_builder_block.call)
104
+ Fino::Pipe::Storage.new(adapter)
105
+ end
106
+
107
+ def adapter
108
+ @adapter ||= configuration.adapter_builder_block.call
101
109
  end
102
110
 
103
111
  def cache
@@ -8,11 +8,11 @@ class Fino::Pipe::Storage
8
8
  end
9
9
 
10
10
  def read(setting_definition)
11
- to_setting(setting_definition, adapter.read(setting_definition))
11
+ to_setting(setting_definition, adapter.read(setting_definition.key))
12
12
  end
13
13
 
14
14
  def read_multi(setting_definitions)
15
- setting_definitions.zip(adapter.read_multi(setting_definitions)).map do |definition, raw_data|
15
+ setting_definitions.zip(adapter.read_multi(setting_definitions.map(&:key))).map do |definition, raw_data|
16
16
  to_setting(definition, raw_data)
17
17
  end
18
18
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fino
4
+ module Solid
5
+ class Adapter
6
+ include Fino::Adapter
7
+
8
+ SCOPE_PREFIX = "s"
9
+ VARIANT_PREFIX = "v"
10
+ VALUE_KEY = "v"
11
+
12
+ def read(setting_key)
13
+ setting = Fino::Solid::Setting.find_by(key: setting_key)
14
+ setting&.data || {}
15
+ end
16
+
17
+ def read_multi(setting_keys)
18
+ settings_by_key = Fino::Solid::Setting.where(key: setting_keys).index_by(&:key)
19
+
20
+ setting_keys.map { |key| settings_by_key[key]&.data || {} }
21
+ end
22
+
23
+ def write(setting_definition, value, overrides, variants)
24
+ serialize_value = ->(raw_value) { setting_definition.type_class.serialize(raw_value) }
25
+
26
+ data = { VALUE_KEY => serialize_value.call(value) }
27
+
28
+ overrides.each do |scope, scope_value|
29
+ data["#{SCOPE_PREFIX}/#{scope}/#{VALUE_KEY}"] = serialize_value.call(scope_value)
30
+ end
31
+
32
+ variants.each do |variant|
33
+ next if variant.value == Fino::AbTesting::Variant::CONTROL_VALUE
34
+
35
+ data["#{VARIANT_PREFIX}/#{variant.percentage}/#{VALUE_KEY}"] = serialize_value.call(variant.value)
36
+ end
37
+
38
+ Fino::Solid::Setting.upsert(
39
+ { key: setting_definition.key, data: data },
40
+ unique_by: :key
41
+ )
42
+ end
43
+
44
+ def read_persisted_setting_keys
45
+ Fino::Solid::Setting.pluck(:key)
46
+ end
47
+
48
+ def clear(setting_key)
49
+ Fino::Solid::Setting.where(key: setting_key).delete_all > 0
50
+ end
51
+
52
+ def fetch_value_from(raw_adapter_data)
53
+ raw_adapter_data.key?(VALUE_KEY) ? raw_adapter_data.delete(VALUE_KEY) : Fino::EMPTINESS
54
+ end
55
+
56
+ def fetch_raw_overrides_from(raw_adapter_data)
57
+ raw_adapter_data.each_with_object({}) do |(key, value), memo|
58
+ next unless key.start_with?("#{SCOPE_PREFIX}/")
59
+
60
+ scope = key.split("/", 3)[1]
61
+ memo[scope] = value
62
+ end
63
+ end
64
+
65
+ def fetch_raw_variants_from(raw_adapter_data)
66
+ raw_adapter_data.each_with_object([]) do |(key, value), memo|
67
+ next unless key.start_with?("#{VARIANT_PREFIX}/")
68
+
69
+ percentage = key.split("/", 3)[1]
70
+
71
+ memo << { percentage: percentage.to_f, value: value }
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "rails/generators/active_record"
5
+
6
+ module Fino
7
+ module Solid
8
+ module Generators
9
+ class InstallGenerator < ::Rails::Generators::Base
10
+ include ::ActiveRecord::Generators::Migration
11
+
12
+ source_root File.expand_path("templates", __dir__)
13
+
14
+ def copy_migration
15
+ migration_template "create_fino_settings.rb.tt", File.join(db_migrate_path, "create_fino_settings.rb")
16
+ end
17
+
18
+ private
19
+
20
+ def db_migrate_path
21
+ "db/migrate"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fino
4
+ module Solid
5
+ class Railtie < ::Rails::Railtie
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fino
4
+ module Solid
5
+ class Record < ActiveRecord::Base
6
+ self.abstract_class = true
7
+
8
+ connects_to(**Fino::Solid.connects_to) if Fino::Solid.connects_to
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fino
4
+ module Solid
5
+ class Setting < Record
6
+ self.table_name = "fino_settings"
7
+
8
+ serialize :data, coder: JSON
9
+
10
+ validates :key, presence: true, uniqueness: true
11
+ end
12
+ end
13
+ end
data/lib/fino/solid.rb ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+
5
+ module Fino
6
+ module Solid
7
+ mattr_accessor :connects_to
8
+
9
+ class << self
10
+ def configure(&block)
11
+ instance_eval(&block)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ require "fino/solid/record"
18
+ require "fino/solid/setting"
19
+ require "fino/solid/adapter"
20
+ require "fino/solid/railtie" if defined?(Rails::Railtie)
21
+
22
+ if defined?(Rails) && defined?(Rails::Generators)
23
+ require "rails/generators"
24
+ require_relative "solid/generators/install/install_generator"
25
+ end
data/lib/fino/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fino
4
- VERSION = "1.3.1"
4
+ VERSION = "1.4.0"
5
5
  REQUIRED_RUBY_VERSION = ">= 3.0.0"
6
6
  end
data/lib/fino-solid.rb ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fino"
4
+ require "fino/solid"
data/lib/fino.rb CHANGED
@@ -91,6 +91,11 @@ Zeitwerk::Loader.for_gem.tap do |l|
91
91
  root_relative_path.call("lib/fino/redis.rb"),
92
92
  root_relative_path.call("lib/fino/redis/"),
93
93
 
94
+ # Fino Solid
95
+ root_relative_path.call("lib/fino-solid.rb"),
96
+ root_relative_path.call("lib/fino/solid.rb"),
97
+ root_relative_path.call("lib/fino/solid/"),
98
+
94
99
  # Other
95
100
  root_relative_path.call("lib/fino/metadata.rb"),
96
101
  root_relative_path.call("lib/fino/railtie.rb")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fino
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Egor Iskrenkov
@@ -31,6 +31,7 @@ extra_rdoc_files: []
31
31
  files:
32
32
  - LICENSE
33
33
  - README.md
34
+ - lib/fino-solid.rb
34
35
  - lib/fino.rb
35
36
  - lib/fino/ab_testing/experiment.rb
36
37
  - lib/fino/ab_testing/variant.rb
@@ -59,6 +60,12 @@ files:
59
60
  - lib/fino/settings/integer.rb
60
61
  - lib/fino/settings/section.rb
61
62
  - lib/fino/settings/string.rb
63
+ - lib/fino/solid.rb
64
+ - lib/fino/solid/adapter.rb
65
+ - lib/fino/solid/generators/install/install_generator.rb
66
+ - lib/fino/solid/railtie.rb
67
+ - lib/fino/solid/record.rb
68
+ - lib/fino/solid/setting.rb
62
69
  - lib/fino/version.rb
63
70
  homepage: https://github.com/eiskrenkov/fino
64
71
  licenses: