optify-config 1.18.0-x86_64-linux → 1.20.0-x86_64-linux

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: 72ce685effaf20e61f50d3b6dbfd7977404de2cce2dc236083354f61ed4ff275
4
- data.tar.gz: 4f36e14bac44774c4e78452d17dcd42b251fc8e91ef62e5064e2115bbfd38cff
3
+ metadata.gz: c0c6af3de09e020f3c54b8ab92039aa9ce0d41cb05509b9326ee1967860d6f14
4
+ data.tar.gz: 6310dda89ed60816ec0c3ad79d37cf65bf57a3a64129aa6939374545cdb424d4
5
5
  SHA512:
6
- metadata.gz: c70b2f22709bfa93c383b51466535eb196697f8920bbd060e7c1f7c08770cac9ef2fc9e2c18473b7cfbb13e18986f56f7c11e2939afc6aad20094e45f550629f
7
- data.tar.gz: 07bec6e9d42b0b2fa7e43f142bfc5a3fac8806fb0bd75b2f2382da127bbcf5b6ff9d7b0bf61c095cbd67d51084184bba0eb4bcf246b55c81f70070045d71df95
6
+ metadata.gz: 6b9332ce87a8fe7093b76de7a4dc199585229d00645378aae2be6a3ff3be1ee6c411a5a866529da5e9066dbbf948c1ca4a56c83989a2ac945bdd9927c106074c
7
+ data.tar.gz: 66f9cda4aa03931b2c0b73b67b9b7cce0fb6bbb6010060132b570e7eb92ddae7edb91f075e937cd7b39a0aa4c7a20dff028b3b8405147ccd9ffe8b276ef50995
Binary file
Binary file
Binary file
@@ -0,0 +1,41 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Optify
5
+ # The mode for the cache.
6
+ module CacheMode
7
+ # Non-thread-safe LRU cache.
8
+ # Should be faster than `THREAD_SAFE` for single-threaded applications.
9
+ NOT_THREAD_SAFE = :not_thread_safe #: Symbol
10
+ # Thread-safe LRU cache.
11
+ THREAD_SAFE = :thread_safe #: Symbol
12
+ end
13
+
14
+ # Options for initializing the cache.
15
+ class CacheInitOptions
16
+ #: Integer?
17
+ attr_reader :max_size
18
+
19
+ # A value from `CacheMode`.
20
+ #
21
+ #: Symbol
22
+ attr_reader :mode
23
+
24
+ # Initializes the cache options.
25
+ # Defaults to a non-thread-safe unlimited size cache for backwards compatibility
26
+ # with how this library was originally configured with an unbounded hash as the case.
27
+ # @param mode A value from `CacheMode`.
28
+ #
29
+ #: (
30
+ #| ?max_size: Integer?,
31
+ #| ?mode: Symbol,
32
+ #| ) -> void
33
+ def initialize(
34
+ max_size: nil,
35
+ mode: CacheMode::NOT_THREAD_SAFE
36
+ )
37
+ @max_size = max_size
38
+ @mode = mode
39
+ end
40
+ end
41
+ end
@@ -4,6 +4,7 @@
4
4
  require 'sorbet-runtime'
5
5
 
6
6
  require_relative './base_config'
7
+ require_relative './cache_init_options'
7
8
  require_relative './options_metadata'
8
9
  require_relative './provider_module'
9
10
 
@@ -32,9 +33,9 @@ module Optify
32
33
 
33
34
  # (Optional) Eagerly initializes the cache.
34
35
  # @return [OptionsProvider] `self`.
35
- #: -> OptionsProvider
36
- def init
37
- _init
36
+ #: (?CacheInitOptions?) -> OptionsProvider
37
+ def init(cache_init_options = nil)
38
+ _init(cache_init_options)
38
39
  self
39
40
  end
40
41
  end
@@ -2,11 +2,47 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'json'
5
+ require 'lru_redux'
5
6
  require 'sorbet-runtime'
6
7
 
7
8
  module Optify
8
9
  # @!visibility private
9
10
  module ProviderModule
11
+ #: [T] (LruRedux::Cache | Hash[untyped, untyped], Array[untyped]) { -> T } -> T
12
+ def self._cache_getset(cache, cache_key, &block)
13
+ if cache.is_a? LruRedux::Cache
14
+ cache.getset(cache_key, &block)
15
+ else
16
+ # Plain Hash - use fetch with block and store result
17
+ cache.fetch(cache_key) do
18
+ result = block.call
19
+ cache[cache_key] = result
20
+ end
21
+ end
22
+ end
23
+
24
+ #: (CacheInitOptions?) -> ( Hash[Array[untyped], untyped] | LruRedux::Cache)
25
+ def self._create_cache(cache_init_options)
26
+ # Be backwards compatible with the original implementation of this library.
27
+ return {} if cache_init_options.nil?
28
+
29
+ max_size = cache_init_options.max_size
30
+ mode = cache_init_options.mode
31
+ if max_size.nil?
32
+ Kernel.raise ArgumentError, 'Thread-safe cache is not supported when max_size is nil' if mode == CacheMode::THREAD_SAFE
33
+ {}
34
+ else
35
+ case mode
36
+ when CacheMode::THREAD_SAFE
37
+ LruRedux::ThreadSafeCache.new(max_size)
38
+ when CacheMode::NOT_THREAD_SAFE
39
+ LruRedux::Cache.new(max_size)
40
+ else
41
+ Kernel.raise ArgumentError, "Invalid cache mode: #{mode}"
42
+ end
43
+ end
44
+ end
45
+
10
46
  #: (Array[String] feature_names) -> Array[String]
11
47
  def get_canonical_feature_names(feature_names)
12
48
  # Try to optimize a typical case where there are just a few features.
@@ -55,7 +91,7 @@ module Optify
55
91
  # @return The options.
56
92
  #: [Config] (String, Array[String], Class[Config], ?CacheOptions?, ?Optify::GetOptionsPreferences?) -> Config
57
93
  def _get_options(key, feature_names, config_class, cache_options = nil, preferences = nil)
58
- return get_options_with_cache(key, feature_names, config_class, cache_options, preferences) if cache_options
94
+ return _get_options_with_cache(key, feature_names, config_class, cache_options, preferences) if cache_options
59
95
 
60
96
  unless config_class.respond_to?(:from_hash)
61
97
  Kernel.raise NotImplementedError,
@@ -73,14 +109,8 @@ module Optify
73
109
  .from_hash(hash)
74
110
  end
75
111
 
76
- #: -> void
77
- def _init
78
- @cache = {} #: Hash[untyped, untyped]?
79
- @features_with_metadata = nil #: Hash[String, OptionsMetadata]?
80
- end
81
-
82
112
  #: [Config] (String key, Array[String] feature_names, Class[Config] config_class, Optify::CacheOptions _cache_options, ?Optify::GetOptionsPreferences? preferences) -> Config
83
- def get_options_with_cache(key, feature_names, config_class, _cache_options, preferences = nil)
113
+ def _get_options_with_cache(key, feature_names, config_class, _cache_options, preferences = nil)
84
114
  # Cache directly in Ruby instead of Rust because:
85
115
  # * Avoid any possible conversion overhead.
86
116
  # * Memory management: probably better to do it in Ruby for a Ruby app and avoid memory in Rust.
@@ -100,22 +130,27 @@ module Optify
100
130
  # Features are filtered, so we don't need the constraints in the cache key.
101
131
  are_configurable_strings_enabled = preferences&.are_configurable_strings_enabled? || false
102
132
  cache_key = [key, feature_names, are_configurable_strings_enabled, config_class]
103
- @cache #: as !nil
104
- .fetch(cache_key) do
133
+ ProviderModule._cache_getset(
134
+ @cache, #: as !nil
135
+ cache_key,
136
+ ) do
105
137
  # Handle a cache miss.
106
138
 
107
139
  # We can avoid converting the features names because they're already converted from filtering above, if that was desired.
108
140
  # We don't need the constraints because we filtered the features above.
109
141
  # We already know there are no overrides because we checked above.
110
- preferences = GetOptionsPreferences.new
111
- preferences.skip_feature_name_conversion = true
112
- preferences.enable_configurable_strings if are_configurable_strings_enabled
142
+ cache_miss_preferences = GetOptionsPreferences.new
143
+ cache_miss_preferences.skip_feature_name_conversion = true
144
+ cache_miss_preferences.enable_configurable_strings if are_configurable_strings_enabled
113
145
 
114
- result = _get_options(key, feature_names, config_class, nil, preferences)
115
-
116
- @cache #: as !nil
117
- .[]= cache_key, result
146
+ _get_options(key, feature_names, config_class, nil, cache_miss_preferences)
118
147
  end
119
148
  end
149
+
150
+ #: (?CacheInitOptions?) -> void
151
+ def _init(cache_init_options = nil)
152
+ @cache = ProviderModule._create_cache(cache_init_options) #: ( Hash[untyped, untyped] | LruRedux::Cache)?
153
+ @features_with_metadata = nil #: Hash[String, OptionsMetadata]?
154
+ end
120
155
  end
121
156
  end
@@ -30,9 +30,9 @@ module Optify
30
30
 
31
31
  # (Optional) Eagerly initializes the cache.
32
32
  # @return [OptionsWatcher] `self`.
33
- #: -> OptionsWatcher
34
- def init
35
- _init
33
+ #: (?CacheInitOptions?) -> OptionsWatcher
34
+ def init(cache_init_options = nil)
35
+ _init(cache_init_options)
36
36
  @cache_creation_time = Time.now #: Time?
37
37
  self
38
38
  end
data/rbi/optify.rbi CHANGED
@@ -3,6 +3,10 @@
3
3
 
4
4
  # Tools for working with configurations declared in files.
5
5
  module Optify
6
+ # Raised when a feature name is not found in the registry.
7
+ class UnknownFeatureError < StandardError
8
+ end
9
+
6
10
  # DEPRECATED: Use `Optify::FromHashable` instead.
7
11
  # A base class for classes from configuration files.
8
12
  # Classes that derive from this can easily be used with `Optify::OptionsProvider.get_options`
@@ -19,6 +23,37 @@ module Optify
19
23
  class CacheOptions < FromHashable
20
24
  end
21
25
 
26
+ # The mode for the cache.
27
+ module CacheMode
28
+ # Non-thread-safe LRU cache.
29
+ # Should be faster than `THREAD_SAFE` for single-threaded applications.
30
+ NOT_THREAD_SAFE = T.let(:not_thread_safe, Symbol)
31
+ # Thread-safe LRU cache.
32
+ THREAD_SAFE = T.let(:thread_safe, Symbol)
33
+ end
34
+
35
+ # Options for initializing the cache.
36
+ class CacheInitOptions
37
+ sig { returns(T.nilable(Integer)) }
38
+ attr_reader :max_size
39
+
40
+ # A value from `CacheMode`.
41
+ sig { returns(Symbol) }
42
+ attr_reader :mode
43
+
44
+ # Initializes the cache options.
45
+ # Defaults to a non-thread-safe unlimited size cache for backwards compatibility
46
+ # with how this library was originally configured with an unbounded hash as the case.
47
+ # @param mode A value from `CacheMode`.
48
+ sig do
49
+ params(
50
+ max_size: T.nilable(Integer),
51
+ mode: Symbol,
52
+ ).void
53
+ end
54
+ def initialize(max_size: nil, mode: CacheMode::NOT_THREAD_SAFE); end
55
+ end
56
+
22
57
  # Information about a feature.
23
58
  class OptionsMetadata < FromHashable
24
59
  sig { returns(T.nilable(T::Array[String])) }
@@ -188,7 +223,7 @@ module Optify
188
223
  sig do
189
224
  params(
190
225
  feature_names: T::Array[String],
191
- preferences: GetOptionsPreferences
226
+ preferences: GetOptionsPreferences,
192
227
  )
193
228
  .returns(T::Array[String])
194
229
  end
@@ -211,7 +246,7 @@ module Optify
211
246
  feature_names: T::Array[String],
212
247
  config_class: T::Class[T.type_parameter(:Config)],
213
248
  cache_options: T.nilable(CacheOptions),
214
- preferences: T.nilable(Optify::GetOptionsPreferences)
249
+ preferences: T.nilable(Optify::GetOptionsPreferences),
215
250
  )
216
251
  .returns(T.type_parameter(:Config))
217
252
  end
@@ -264,8 +299,11 @@ module Optify
264
299
 
265
300
  # (Optional) Eagerly initializes the cache.
266
301
  # @return `self`.
267
- sig { returns(T.self_type) }
268
- def init; end
302
+ sig do
303
+ params(cache_init_options: T.nilable(CacheInitOptions))
304
+ .returns(T.self_type)
305
+ end
306
+ def init(cache_init_options = nil); end
269
307
 
270
308
  private
271
309
 
data/sig/optify.rbs CHANGED
@@ -2,6 +2,10 @@
2
2
  module Optify
3
3
  end
4
4
 
5
+ # Raised when a feature name is not found in the registry.
6
+ class Optify::UnknownFeatureError < StandardError
7
+ end
8
+
5
9
  # DEPRECATED: Use `Optify::FromHashable` instead.
6
10
  # A base class for classes from configuration files.
7
11
  # Classes that derive from this can easily be used with `Optify::OptionsProvider.get_options`
@@ -17,6 +21,22 @@ end
17
21
  class Optify::CacheOptions < FromHashable
18
22
  end
19
23
 
24
+ # The mode for the cache.
25
+ module Optify::CacheMode
26
+ end
27
+
28
+ Optify::Optify::CacheMode::NOT_THREAD_SAFE: Symbol
29
+
30
+ Optify::Optify::CacheMode::THREAD_SAFE: Symbol
31
+
32
+ # Options for initializing the cache.
33
+ class Optify::CacheInitOptions
34
+ # A value from `CacheMode`.
35
+ def initialize: () -> Integer?
36
+ | () -> Symbol
37
+ | (?max_size: Integer? max_size, ?mode: Symbol mode) -> void
38
+ end
39
+
20
40
  # Information about a feature.
21
41
  class Optify::OptionsMetadata < FromHashable
22
42
  def aliases: () -> ::Array[String]?
@@ -163,9 +183,7 @@ module Optify::ProviderModule
163
183
  # @return Whether the feature has conditions.
164
184
  def conditions?: (String canonical_feature_name) -> bool
165
185
 
166
- # (Optional) Eagerly initializes the cache.
167
- # @return `self`.
168
- def init: () -> self
186
+ def init: (?CacheInitOptions? cache_init_options) -> self
169
187
 
170
188
  # Map aliases or canonical feature names (perhaps derived from a file names) to the canonical feature names.
171
189
  # Canonical feature names map to themselves.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optify-config
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.0
4
+ version: 1.20.0
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - Justin D. Harris
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-12-10 00:00:00.000000000 Z
11
+ date: 2026-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: optify-from_hash
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.2.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: sin_lru_redux
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.5.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.5.2
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: sorbet-runtime
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -78,14 +92,14 @@ dependencies:
78
92
  requirements:
79
93
  - - "~>"
80
94
  - !ruby/object:Gem::Version
81
- version: 1.76.1
95
+ version: 1.82.1
82
96
  type: :development
83
97
  prerelease: false
84
98
  version_requirements: !ruby/object:Gem::Requirement
85
99
  requirements:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
- version: 1.76.1
102
+ version: 1.82.1
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: rubocop-sorbet
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -161,6 +175,7 @@ files:
161
175
  - lib/optify_ruby/3.3/optify_ruby.so
162
176
  - lib/optify_ruby/3.4/optify_ruby.so
163
177
  - lib/optify_ruby/base_config.rb
178
+ - lib/optify_ruby/cache_init_options.rb
164
179
  - lib/optify_ruby/get_options_preferences.rb
165
180
  - lib/optify_ruby/implementation.rb
166
181
  - lib/optify_ruby/options_metadata.rb