typed_cache 0.3.1 → 0.4.0.pre.1

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/typed_cache/backend.rb +80 -2
  4. data/lib/typed_cache/backends/active_support.rb +24 -98
  5. data/lib/typed_cache/backends/memory.rb +22 -73
  6. data/lib/typed_cache/backends.rb +2 -2
  7. data/lib/typed_cache/cache_builder.rb +131 -46
  8. data/lib/typed_cache/cache_key.rb +1 -1
  9. data/lib/typed_cache/cache_ref.rb +24 -55
  10. data/lib/typed_cache/decorator.rb +22 -12
  11. data/lib/typed_cache/decorators/instrumented.rb +12 -19
  12. data/lib/typed_cache/decorators.rb +7 -1
  13. data/lib/typed_cache/either.rb +28 -0
  14. data/lib/typed_cache/instrumenters.rb +6 -2
  15. data/lib/typed_cache/maybe.rb +28 -0
  16. data/lib/typed_cache/namespace.rb +1 -3
  17. data/lib/typed_cache/snapshot.rb +6 -0
  18. data/lib/typed_cache/store.rb +130 -78
  19. data/lib/typed_cache/version.rb +1 -1
  20. data/lib/typed_cache.rb +5 -2
  21. data/rbi/typed_cache/backend.rbi +44 -2
  22. data/rbi/typed_cache/backends/active_support.rbi +1 -1
  23. data/rbi/typed_cache/backends/memory.rbi +1 -1
  24. data/rbi/typed_cache/cache_builder.rbi +29 -10
  25. data/rbi/typed_cache/cache_key.rbi +14 -0
  26. data/rbi/typed_cache/cache_ref.rbi +6 -15
  27. data/rbi/typed_cache/decorator.rbi +23 -37
  28. data/rbi/typed_cache/decorators/instrumented.rbi +1 -1
  29. data/rbi/typed_cache/either.rbi +24 -0
  30. data/rbi/typed_cache/maybe.rbi +24 -0
  31. data/rbi/typed_cache/namespace.rbi +14 -0
  32. data/rbi/typed_cache/snapshot.rbi +6 -0
  33. data/rbi/typed_cache/store.rbi +26 -24
  34. data/rbi/typed_cache.rbi +1 -1
  35. data/sig/generated/typed_cache/backend.rbs +68 -2
  36. data/sig/generated/typed_cache/backends/active_support.rbs +13 -21
  37. data/sig/generated/typed_cache/backends/memory.rbs +10 -30
  38. data/sig/generated/typed_cache/backends.rbs +2 -2
  39. data/sig/generated/typed_cache/cache_builder.rbs +57 -16
  40. data/sig/generated/typed_cache/cache_ref.rbs +16 -37
  41. data/sig/generated/typed_cache/decorator.rbs +18 -6
  42. data/sig/generated/typed_cache/decorators/instrumented.rbs +3 -7
  43. data/sig/generated/typed_cache/decorators.rbs +9 -1
  44. data/sig/generated/typed_cache/either.rbs +24 -0
  45. data/sig/generated/typed_cache/instrumenters.rbs +4 -3
  46. data/sig/generated/typed_cache/maybe.rbs +24 -0
  47. data/sig/generated/typed_cache/namespace.rbs +0 -2
  48. data/sig/generated/typed_cache/snapshot.rbs +6 -0
  49. data/sig/generated/typed_cache/store.rbs +49 -42
  50. data/sig/generated/typed_cache.rbs +6 -2
  51. data.tar.gz.sig +0 -0
  52. metadata +3 -3
  53. metadata.gz.sig +0 -0
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TypedCache
4
- # @rbs!
5
- #
6
-
7
4
  # Generic interface for type-safe cache storage implementations
8
5
  # All stores are assumed to handle namespacing internally
9
6
  #
@@ -12,31 +9,38 @@ module TypedCache
12
9
  # - Queries (get, key?, fetch) ask questions without side effects
13
10
  #
14
11
  # @rbs generic V
15
- module Store
12
+ class Store
16
13
  # @rbs! type cache_key = String | CacheKey
17
14
 
18
15
  # @rbs!
19
16
  # interface _Store[V]
20
- # def read: (cache_key) -> either[Error, Snapshot[V]]
21
- # def read_all: (Array[cache_key]) -> either[Error, Array[Snapshot[V]]]
17
+ # def read: (cache_key) -> either[Error, Snapshot[maybe[V]]]
18
+ # def read_all: (Array[cache_key]) -> either[Error, Hash[CacheKey, Snapshot[V]]]
22
19
  # def ref: (cache_key) -> CacheRef[V]
23
20
  # def write: (cache_key, V) -> either[Error, Snapshot[V]]
24
- # def write_all: (Hash[cache_key, V]) -> either[Error, Array[Snapshot[V]]]
25
- # def delete: (cache_key) -> either[Error, Snapshot[V]]
21
+ # def write_all: (Hash[cache_key, V]) -> either[Error, Hash[CacheKey, Snapshot[V]]]
22
+ # def delete: (cache_key) -> either[Error, maybe[V]]
26
23
  # def key?: (cache_key) -> bool
27
- # def clear: () -> maybe[Error]
28
- # def fetch: (cache_key) { () -> V? } -> either[Error, Snapshot[maybe[V]]]
24
+ # def clear: () -> void
25
+ # def fetch: (cache_key) { (CacheKey) -> V? } -> either[Error, Snapshot[maybe[V]]]
29
26
  # def fetch_all: (Array[cache_key]) { (CacheKey) -> V? } -> either[Error, Array[Snapshot[V]]]
27
+ # def fetch_or_compute_all: (Array[cache_key]) { (Array[CacheKey]) -> Hash[CacheKey, V] } -> either[Error, Hash[CacheKey, Snapshot[V]]]
30
28
  # def namespace: () -> Namespace
31
29
  # def with_namespace: (Namespace) -> Store[V]
32
- # def store_type: () -> String
30
+ # def at_namespace: (Namespace) -> Store[V]
31
+ # def cache_for: [T] (Class[T], at: (Namespace | String | Array[String])) -> Store[T]
32
+ # def backend: () -> Backend[V]
33
33
  # end
34
34
  # include _Store[V]
35
35
 
36
- # @rbs!
37
- # interface _Decorator[V]
38
- # def initialize: (Store[V]) -> void
39
- # end
36
+ attr_reader :namespace #: Namespace
37
+ attr_reader :backend #: Backend[V]
38
+
39
+ # @rbs (Namespace, Backend[V]) -> void
40
+ def initialize(namespace, backend)
41
+ @namespace = namespace
42
+ @backend = backend
43
+ end
40
44
 
41
45
  # @rbs (Store[V]) -> void
42
46
  def initialize_copy(other)
@@ -45,18 +49,33 @@ module TypedCache
45
49
  end
46
50
 
47
51
  # Retrieves a value from the cache
48
- # @rbs (cache_key, **top) -> either[Error, Snapshot[V]]
52
+ # @rbs (cache_key, **top) -> either[Error, Snapshot[maybe[V]]]
49
53
  def read(key, **kwargs)
50
- Either.left(NotImplementedError.new("#{self.class} must implement #read"))
54
+ key = namespaced_key(key)
55
+
56
+ value = backend.read(key, **kwargs)
57
+
58
+ Either.right(
59
+ if value.nil?
60
+ Snapshot.cached(key, Maybe.none)
61
+ else
62
+ Snapshot.cached(key, Maybe.some(value))
63
+ end,
64
+ )
65
+ rescue => e
66
+ Either.left(StoreError.new(:read, key, "Failed to read from cache: #{e.message}", e))
51
67
  end
52
68
 
53
- # @rbs (Array[cache_key], **top) -> either[Error, Hash[cache_key, Snapshot[V]]]
69
+ # @rbs (Array[cache_key], **top) -> either[Error, Hash[CacheKey, Snapshot[V]]]
54
70
  def read_all(keys, **kwargs)
55
- keys.map { |key| read(key, **kwargs) }.reduce(Either.right({})) do |acc, result|
56
- acc.bind do |values|
57
- result.map { |value| values.merge(value.key => value) }
58
- end
59
- end
71
+ keys = keys.map { |key| namespaced_key(key) }
72
+ cached_values = backend.read_multi(keys, **kwargs)
73
+
74
+ keys.filter_map do |key|
75
+ next unless cached_values.key?(key.to_s)
76
+
77
+ [key, Snapshot.cached(key, cached_values[key.to_s])]
78
+ end.to_h
60
79
  end
61
80
 
62
81
  # Retrieves a cache reference for a key
@@ -68,76 +87,105 @@ module TypedCache
68
87
  # Stores a value in the cache
69
88
  # @rbs (cache_key, V, **top) -> either[Error, Snapshot[V]]
70
89
  def write(key, value, **kwargs)
71
- Either.left(NotImplementedError.new("#{self.class} must implement #write"))
90
+ key = namespaced_key(key)
91
+ backend.write(key, value, **kwargs)
92
+
93
+ Either.right(Snapshot.cached(key, value))
94
+ rescue => e
95
+ Either.left(StoreError.new(:write, key, "Failed to write to cache: #{e.message}", e))
72
96
  end
73
97
 
74
- # @rbs (Hash[cache_key, V], **top) -> either[Error, Hash[cache_key, Snapshot[V]]]
98
+ # @rbs (Hash[cache_key, V], **top) -> either[Error, Hash[CacheKey, Snapshot[V]]]
99
+
75
100
  def write_all(values, **kwargs)
76
- values.map { |key, value| write(key, value, **kwargs) }.reduce(Either.right({})) do |acc, result|
77
- acc.bind do |values|
78
- result.map { |value| values.merge(value.key => value) }
79
- end
80
- end
101
+ values.transform_keys! { |key| namespaced_key(key) }
102
+
103
+ written_values = backend.write_multi(values, **kwargs)
104
+ written_values.transform_values { |value| Snapshot.cached(key, value) }
81
105
  end
82
106
 
83
107
  # Removes a value from the cache, returning the removed value
84
- # @rbs (cache_key) -> either[Error, Snapshot[V]]
108
+ # @rbs (cache_key) -> either[Error, maybe[V]]
85
109
  def delete(key)
86
- Either.left(NotImplementedError.new("#{self.class} must implement #delete"))
110
+ key = namespaced_key(key)
111
+ deleted_value = backend.delete(key)
112
+
113
+ Either.right(Maybe.wrap(deleted_value))
114
+ rescue => e
115
+ Either.left(StoreError.new(:delete, key, "Failed to delete from cache: #{e.message}", e))
87
116
  end
88
117
 
89
118
  # Checks if a key exists in the cache (query operation)
90
119
  # @rbs (cache_key) -> bool
91
120
  def key?(key)
92
- false # Safe default - assume key doesn't exist
121
+ key = namespaced_key(key)
122
+ backend.key?(key)
93
123
  end
94
124
 
95
125
  # Clears all values from the cache namespace (command operation)
96
- # @rbs () -> maybe[Error]
126
+ # @rbs () -> void
97
127
  def clear
98
- Maybe.some(NotImplementedError.new("#{self.class} does not implement #clear"))
128
+ backend.clear
99
129
  end
100
130
 
101
131
  # Fetches a value from cache, computing and storing it if not found
102
132
  # This is an atomic operation that combines read and write
103
- # @rbs (cache_key, **top) { () -> V } -> either[Error, Snapshot[V]]
133
+ # @rbs (cache_key, **top) { (CacheKey) -> V? } -> either[Error, Snapshot[maybe[V]]]
104
134
  def fetch(key, **kwargs, &block)
105
- # Default implementation using read/write pattern
106
- read_result = read(key)
107
- return read_result if read_result.right?
108
-
109
- # Only proceed if it's a cache miss
110
- return read_result unless read_result.error.is_a?(CacheMissError)
111
-
112
- # Compute and store new value
113
- begin
114
- computed_value = yield
115
- write(key, computed_value, **kwargs)
116
- Either.right(Snapshot.computed(key, computed_value))
117
- rescue => e
118
- Either.left(StoreError.new(:fetch, key, "Failed to compute value for key '#{key}': #{e.message}", e))
135
+ key = namespaced_key(key)
136
+ computed = false
137
+ result = backend.fetch(key, **kwargs) do
138
+ computed = true
139
+ yield(key)
140
+ end
141
+
142
+ if result.nil?
143
+ Either.right(Snapshot.cached(key, Maybe.none))
144
+ else
145
+ snapshot = computed ? Snapshot.computed(key, result) : Snapshot.cached(key, result)
146
+ Either.right(snapshot.map { Maybe.wrap(_1) })
119
147
  end
148
+ rescue => e
149
+ Either.left(StoreError.new(:fetch, key, "Failed to fetch from cache: #{e.message}", e))
120
150
  end
121
151
 
122
- # @rbs (Array[cache_key], **top) { (CacheKey) -> V } -> either[Error, Array[Snapshot[V]]]
152
+ # @rbs (Array[cache_key], **top) { (CacheKey) -> V? } -> either[Error, Hash[CacheKey, Snapshot[V]]]
123
153
  def fetch_all(keys, **kwargs, &block)
124
154
  keys = keys.map { |key| namespaced_key(key) }
125
- keys.reduce(Either.right([])) do |acc, key|
126
- acc.bind do |values|
127
- fetch(key. **kwargs) { yield(key) }.map { |value| values + [value] }
128
- end
155
+ computed_keys = Set.new
156
+ fetched_values = backend.fetch_multi(keys, **kwargs) do |key|
157
+ computed_keys << key
158
+ yield(key)
129
159
  end
160
+
161
+ Either.right(keys.to_h do |key|
162
+ snapshot = computed_keys.include?(key) ? Snapshot.computed(key, fetched_values[key]) : Snapshot.cached(key, fetched_values[key])
163
+ [key, snapshot]
164
+ end)
165
+ rescue => e
166
+ Either.left(StoreError.new(:fetch_all, keys, "Failed to fetch from cache: #{e.message}", e))
130
167
  end
131
168
 
132
- # @rbs () -> Instrumenter
133
- def instrumenter = Instrumenters::Null.instance
169
+ # @rbs (Array[cache_key], **top) { (Array[CacheKey]) -> Hash[CacheKey, V] } -> either[Error, Hash[CacheKey, Snapshot[V]]]
170
+ def fetch_or_compute_all(keys, **kwargs, &block)
171
+ keys = keys.map { |key| namespaced_key(key) }
172
+ cached_values = backend.read_multi(keys, **kwargs)
173
+ missing_keys = keys - cached_values.keys
174
+
175
+ if missing_keys.any?
176
+ computed_values = yield(missing_keys)
177
+ backend.write_multi(computed_values, **kwargs)
178
+ end
134
179
 
135
- # Returns the namespace for this store (for instrumentation/debugging)
136
- # @rbs () -> Namespace
137
- def namespace
138
- raise NotImplementedError, "#{self.class} must implement #namespace"
180
+ cached_values.transform_values! { |value| Snapshot.cached(key, value) }
181
+ computed_values.transform_values! { |value| Snapshot.computed(key, value) }
182
+
183
+ cached_values.merge(computed_values)
139
184
  end
140
185
 
186
+ # @rbs () -> Instrumenter
187
+ def instrumenter = @instrumenter ||= Instrumenters::Null.new(namespace:)
188
+
141
189
  # Accepts a String segment or a fully-formed Namespace and returns a cloned
142
190
  # store scoped to that namespace.
143
191
  #: (Namespace | String | Array[String]) -> Store[V]
@@ -154,34 +202,38 @@ module TypedCache
154
202
  clone.tap { |store| store.namespace = new_namespace }
155
203
  end
156
204
 
157
- # Returns the store type identifier for instrumentation/debugging
158
- # @rbs () -> String
159
- def store_type
160
- snake_case(self.class.name.split('::').last)
205
+ # @rbs [T] (Class[T], at: (Namespace | String | Array[String])) -> Store[T]
206
+ def cache_for(klass, at: nil)
207
+ new_namespace =
208
+ case at
209
+ when Namespace then at
210
+ when Array then namespace.join(*at)
211
+ else
212
+ namespace.nested(at.to_s)
213
+ end
214
+
215
+ clone.tap { |store| store.namespace = new_namespace }
161
216
  end
162
217
 
218
+ alias at_namespace with_namespace
219
+
220
+ # @rbs () -> String
221
+ def to_s = "Store(#{namespace})"
222
+
223
+ # @rbs () -> String
224
+ def inspect = "Store(#{namespace}, #{backend.inspect})"
225
+
163
226
  protected
164
227
 
165
- attr_writer :namespace #: Namespace
228
+ attr_writer :namespace
166
229
 
167
230
  private
168
231
 
169
- #: (String) -> String
170
- def snake_case(string)
171
- string
172
- .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
173
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
174
- .tr('-', '_')
175
- .downcase
176
- end
177
-
178
232
  #: (cache_key) -> CacheKey
179
233
  def namespaced_key(key)
180
234
  key.is_a?(CacheKey) ? key : CacheKey.new(namespace, key)
181
235
  end
182
236
  end
183
237
 
184
- # @rbs! type backend[V] = Store::_Store[V]
185
- # @rbs! type decorator[V] = backend[V] & Store::_Decorator[V]
186
- # @rbs! type store[V] = backend[V] | decorator[V]
238
+ # @rbs! type store[V] = Store::_Store[V]
187
239
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TypedCache
4
- VERSION = '0.3.1'
4
+ VERSION = '0.4.0-1'
5
5
  end
data/lib/typed_cache.rb CHANGED
@@ -34,6 +34,7 @@ module TypedCache
34
34
  # interface _TypedCacheInstrumentationConfig
35
35
  # def enabled: -> bool
36
36
  # def namespace: -> String
37
+ # def instrumenter: -> Symbol
37
38
  # end
38
39
 
39
40
  # @rbs!
@@ -56,10 +57,12 @@ module TypedCache
56
57
  end
57
58
 
58
59
  class << self
60
+ # @rbs! type cache_definition = TypedCache::_CacheDefinition
61
+
59
62
  # Returns a CacheBuilder with the fluent interface
60
- # @rbs [V] () -> CacheBuilder[V]
63
+ # @rbs () -> cache_definition
61
64
  def builder
62
- CacheBuilder.new(config, Backends, Decorators)
65
+ CacheBuilder.new(CacheDefinition.new, Backends, Decorators)
63
66
  end
64
67
 
65
68
  # @rbs! def config: -> _TypedCacheConfig
@@ -3,7 +3,49 @@
3
3
  module TypedCache
4
4
  module Backend
5
5
  extend T::Generic
6
- include ::TypedCache::Store
7
- CachedType = type_member
6
+
7
+ interface!
8
+
9
+ BackendType = type_member
10
+
11
+ KeyValue = T.type_alias { T.any(CacheKey, String) }
12
+
13
+ sig { abstract.params(key: KeyValue, opts: T::Hash[Symbol, T.untyped]).returns(Either[Error, Snapshot[Maybe[BackendType]]]) }
14
+ def read(key, **opts); end
15
+
16
+ sig { abstract.params(key: KeyValue, value: BackendType, opts: T::Hash[Symbol, T.untyped]).returns(Either[Error, Snapshot[BackendType]]) }
17
+ def write(key, value, **opts); end
18
+
19
+ sig { abstract.params(key: KeyValue).returns(Either[Error, Snapshot[Maybe[BackendType]]]) }
20
+ def delete(key); end
21
+
22
+ sig { abstract.params(keys: T::Array[KeyValue], opts: T::Hash[Symbol, T.untyped]).returns(Either[Error, T::Hash[KeyValue, Snapshot[BackendType]]]) }
23
+ def read_multi(keys, **opts); end
24
+
25
+ sig { abstract.params(values: T::Hash[KeyValue, BackendType], opts: T::Hash[Symbol, T.untyped]).returns(Either[Error, T::Hash[KeyValue, Snapshot[BackendType]]]) }
26
+ def write_multi(values, **opts); end
27
+
28
+ sig { abstract.void }
29
+ def clear; end
30
+
31
+ sig { abstract.params(key: KeyValue).returns(T::Boolean) }
32
+ def key?(key); end
33
+
34
+ sig { abstract.returns(T.nilable(Instrumenter)) }
35
+ def instrumenter; end
36
+
37
+ sig do
38
+ abstract
39
+ .type_parameters(:K)
40
+ .params(key: T.all(KeyValue, T.type_parameter(:K)), block: T.proc.params(key: T.all(KeyValue, T.type_parameter(:K))).returns(T.nilable(BackendType))).returns(Either[Error, Snapshot[Maybe[BackendType]]])
41
+ end
42
+ def fetch(key, &block); end
43
+
44
+ sig do
45
+ abstract
46
+ .type_parameters(:K)
47
+ .params(keys: T::Array[T.all(KeyValue, T.type_parameter(:K))], block: T.proc.params(key: T.all(KeyValue, T.type_parameter(:K))).returns(T.nilable(BackendType))).returns(Either[Error, T::Hash[KeyValue, Snapshot[BackendType]]])
48
+ end
49
+ def fetch_multi(keys, &block); end
8
50
  end
9
51
  end
@@ -7,7 +7,7 @@ module TypedCache
7
7
 
8
8
  include ::TypedCache::Backend
9
9
 
10
- CachedType = type_member
10
+ BackendType = type_member
11
11
  end
12
12
  end
13
13
  end
@@ -7,7 +7,7 @@ module TypedCache
7
7
 
8
8
  include ::TypedCache::Backend
9
9
 
10
- CachedType = type_member
10
+ BackendType = type_member
11
11
  end
12
12
  end
13
13
  end
@@ -1,23 +1,42 @@
1
1
  # typed: strict
2
2
 
3
3
  module TypedCache
4
- class CacheBuilder
5
- Error = T.type_alias { TypedCache::Error }
6
- Config = T.type_alias { ::TypedCache::Private::Configuration }
7
- InstrumenterSource = T.type_alias { T.any(Symbol, ::TypedCache::Instrumenter) }
4
+ module CacheDefinition
5
+ extend T::Sig
6
+ extend T::Helpers
8
7
 
9
- private_constant :Config, :Error, :InstrumenterSource
8
+ InstrumenterSource = T.type_alias { T.any(Symbol, ::TypedCache::Instrumenter) }
10
9
 
11
- sig { params(namespace: ::TypedCache::Namespace).returns(::TypedCache::Either[Error, ::TypedCache::Store[T.anything]]) }
12
- def build(namespace = T.unsafe(nil)); end
10
+ interface!
11
+ sealed!
13
12
 
14
- sig { params(name: Symbol, args: T.untyped, options: T::Hash[Symbol, T.anything]).returns(T.self_type) }
13
+ sig { abstract.params(name: Symbol, args: T.untyped, options: T::Hash[Symbol, T.anything]).returns(T.all(CacheDefinition, CacheBuilder)) }
15
14
  def with_backend(name, *args, **options); end
16
15
 
17
- sig { params(name: Symbol, options: T::Hash[Symbol, T.anything]).returns(T.self_type) }
16
+ sig { abstract.params(name: Symbol, options: T::Hash[Symbol, T.anything]).returns(T.self_type) }
18
17
  def with_decorator(name, **options); end
19
18
 
20
- sig { params(source: InstrumenterSource).returns(T.self_type) }
19
+ sig { abstract.params(source: InstrumenterSource).returns(T.self_type) }
21
20
  def with_instrumentation(source = T.unsafe(nil)); end
22
21
  end
22
+
23
+ module CacheBuilder
24
+ extend T::Sig
25
+ extend T::Helpers
26
+
27
+ interface!
28
+ sealed!
29
+
30
+ sig { abstract.params(namespace: ::TypedCache::Namespace).returns(::TypedCache::Either[::TypedCache::Error, ::TypedCache::Store[T.untyped]]) }
31
+ def build(namespace = T.unsafe(nil)); end
32
+
33
+ sig { abstract.params(namespace: ::TypedCache::Namespace).returns(::TypedCache::Store[T.untyped]) }
34
+ def build!(namespace = T.unsafe(nil)); end
35
+
36
+ sig { abstract.returns(::TypedCache::Either[::TypedCache::Error, ::TypedCache::Backend[T.untyped]]) }
37
+ def build_backend; end
38
+
39
+ sig { abstract.returns(::TypedCache::Backend[T.untyped]) }
40
+ def build_backend!; end
41
+ end
23
42
  end
@@ -12,5 +12,19 @@ module TypedCache
12
12
 
13
13
  sig { returns(String) }
14
14
  def to_s; end
15
+
16
+ sig { returns(String) }
17
+ def inspect; end
18
+
19
+ sig { returns(Integer) }
20
+ def hash; end
21
+
22
+ sig { params(other: Object).returns(T::Boolean) }
23
+ def ==(other); end
24
+
25
+ private
26
+
27
+ sig { returns(String) }
28
+ def delimiter; end
15
29
  end
16
30
  end
@@ -29,28 +29,19 @@ module TypedCache
29
29
  sig { params(block: T.proc.params(value: RefType).returns(RefType)).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[RefType]]) }
30
30
  def update(&block); end
31
31
 
32
- sig { params(default: RefType).returns(RefType) }
33
- def value_or(default); end
34
-
35
- sig { returns(::TypedCache::Maybe[RefType]) }
36
- def value_maybe; end
37
-
38
32
  sig { params(block: T.proc.params(value: RefType).returns(RefType)).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[RefType]]) }
39
33
  def compute_if_absent(&block); end
40
34
 
41
- sig { params(new_key: String).returns(::TypedCache::CacheRef[RefType]) }
42
- def with_key(new_key); end
43
-
44
- sig { params(scope_key: String).returns(::TypedCache::CacheRef[RefType]) }
45
- def scope(scope_key); end
46
-
47
- sig { type_parameters(:T).params(left_fn: T.proc.params(value: Error).returns(T.type_parameter(:T)), right_fn: T.proc.params(value: ::TypedCache::Snapshot[RefType]).returns(T.type_parameter(:T))).returns(T.type_parameter(:T)) }
48
- def fold(left_fn, right_fn); end
49
-
50
35
  sig { type_parameters(:T).params(block: T.proc.params(value: ::TypedCache::Snapshot[RefType]).returns(T.type_parameter(:T))).returns(::TypedCache::Either[Error, T.type_parameter(:T)]) }
51
36
  def with_snapshot(&block); end
52
37
 
53
38
  sig { type_parameters(:T).params(block: T.proc.params(value: RefType).returns(T.type_parameter(:T))).returns(::TypedCache::Either[Error, T.type_parameter(:T)]) }
54
39
  def with(&block); end
40
+
41
+ sig { returns(String) }
42
+ def to_s; end
43
+
44
+ sig { returns(String) }
45
+ def inspect; end
55
46
  end
56
47
  end
@@ -4,64 +4,50 @@ module TypedCache
4
4
  module Decorator
5
5
  extend T::Generic
6
6
 
7
- include ::TypedCache::Store
7
+ include ::TypedCache::Backend
8
8
 
9
9
  abstract!
10
10
 
11
- CachedType = type_member
11
+ BackendType = type_member
12
+ KeyValue = T.type_alias { TypedCache::Backend::KeyValue }
12
13
 
13
- sig { params(store: ::TypedCache::Store[CachedType]).void }
14
- def initialize(store); end
14
+ sig { params(backend: ::TypedCache::Backend[BackendType]).void }
15
+ def initialize(backend); end
15
16
 
16
- sig { overridable.returns(::TypedCache::Store[CachedType]) }
17
- def store; end
17
+ sig { abstract.returns(::TypedCache::Backend[BackendType]) }
18
+ def backend; end
18
19
 
19
- sig(:final) { params(key: T.any(String, ::TypedCache::CacheKey)).returns(::TypedCache::CacheRef[CachedType]) }
20
- def ref(key); end
20
+ sig { override.params(key: KeyValue, opts: T::Hash[Symbol, T.untyped]).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[Maybe[BackendType]]]) }
21
+ def read(key, **opts); end
21
22
 
22
- sig { overridable.params(key: T.any(String, ::TypedCache::CacheKey)).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[CachedType]]) }
23
- def read(key); end
23
+ sig { override.params(key: KeyValue, value: BackendType, opts: T::Hash[Symbol, T.untyped]).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[BackendType]]) }
24
+ def write(key, value, **opts); end
24
25
 
25
- sig { overridable.params(key: T.any(String, ::TypedCache::CacheKey), value: CachedType).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[CachedType]]) }
26
- def write(key, value); end
27
-
28
- sig { overridable.params(key: T.any(String, ::TypedCache::CacheKey)).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[CachedType]]) }
26
+ sig { override.params(key: KeyValue).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[Maybe[BackendType]]]) }
29
27
  def delete(key); end
30
28
 
31
- sig { overridable.params(key: T.any(String, ::TypedCache::CacheKey)).returns(T::Boolean) }
29
+ sig { override.params(key: KeyValue).returns(T::Boolean) }
32
30
  def key?(key); end
33
31
 
34
- sig { overridable.params(key: T.any(String, ::TypedCache::CacheKey), block: T.proc.params(value: CachedType).returns(CachedType)).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[CachedType]]) }
35
- def fetch(key, &block); end
32
+ sig { override.params(key: KeyValue, opts: T::Hash[Symbol, T.untyped], block: T.proc.returns(T.nilable(BackendType))).returns(::TypedCache::Either[Error, ::TypedCache::Snapshot[Maybe[BackendType]]]) }
33
+ def fetch(key, **opts, &block); end
36
34
 
37
- sig { overridable.params(keys: T::Array[T.any(String, ::TypedCache::CacheKey)]).returns(::TypedCache::Either[Error, T::Array[::TypedCache::Snapshot[CachedType]]]) }
38
- def read_all(keys); end
35
+ sig { override.params(keys: T::Array[KeyValue], opts: T::Hash[Symbol, T.untyped]).returns(::TypedCache::Either[Error, T::Hash[KeyValue, Snapshot[BackendType]]]) }
36
+ def read_multi(keys, **opts); end
39
37
 
40
- sig { overridable.params(keys: T::Array[T.any(String, ::TypedCache::CacheKey)], block: T.proc.params(key: T.any(String, ::TypedCache::CacheKey)).returns(CachedType)).returns(::TypedCache::Either[Error, T::Array[::TypedCache::Snapshot[CachedType]]]) }
41
- def fetch_all(keys, &block); end
38
+ sig { override.params(keys: T::Array[KeyValue], opts: T::Hash[Symbol, T.untyped], block: T.proc.params(key: KeyValue).returns(T.nilable(BackendType))).returns(::TypedCache::Either[Error, T::Hash[KeyValue, Snapshot[BackendType]]]) }
39
+ def fetch_multi(keys, **opts, &block); end
42
40
 
43
- sig { overridable.params(values: T::Hash[T.any(String, ::TypedCache::CacheKey), CachedType]).returns(::TypedCache::Either[Error, T::Array[::TypedCache::Snapshot[CachedType]]]) }
44
- def write_all(values); end
41
+ sig { override.params(values: T::Hash[KeyValue, BackendType], opts: T::Hash[Symbol, T.untyped]).returns(::TypedCache::Either[Error, T::Hash[KeyValue, Snapshot[BackendType]]]) }
42
+ def write_multi(values, **opts); end
45
43
 
46
- sig { overridable.void }
44
+ sig { override.void }
47
45
  def clear; end
48
46
 
49
- sig(:final) { returns(::TypedCache::Namespace) }
50
- def namespace; end
51
-
52
- sig(:final) { params(namespace: ::TypedCache::Namespace).returns(::TypedCache::Store[CachedType]) }
53
- def with_namespace(namespace); end
54
-
55
- sig { abstract.returns(String) }
56
- def store_type; end
57
-
58
47
  sig { overridable.params(other: T.self_type).void }
59
48
  def initialize_copy(other); end
60
49
 
61
- sig(:final) { params(key: T.any(String, ::TypedCache::CacheKey)).returns(::TypedCache::CacheKey) }
62
- def namespaced_key(key); end
63
-
64
- sig { overridable.returns(::TypedCache::Instrumenter) }
50
+ sig { override.returns(T.nilable(::TypedCache::Instrumenter)) }
65
51
  def instrumenter; end
66
52
  end
67
53
  end
@@ -7,7 +7,7 @@ module TypedCache
7
7
 
8
8
  include ::TypedCache::Decorator
9
9
 
10
- CachedType = type_member
10
+ BackendType = type_member
11
11
  end
12
12
  end
13
13
  end
@@ -78,6 +78,18 @@ module TypedCache
78
78
 
79
79
  sig { returns(T.noreturn) }
80
80
  def right_or_raise!; end
81
+
82
+ sig { returns(String) }
83
+ def to_s; end
84
+
85
+ sig { returns(String) }
86
+ def inspect; end
87
+
88
+ sig { params(other: Object).returns(T::Boolean) }
89
+ def ==(other); end
90
+
91
+ sig { returns(Integer) }
92
+ def hash; end
81
93
  end
82
94
 
83
95
  class Right
@@ -118,5 +130,17 @@ module TypedCache
118
130
 
119
131
  sig { returns(R) }
120
132
  def right_or_raise!; end
133
+
134
+ sig { returns(String) }
135
+ def to_s; end
136
+
137
+ sig { returns(String) }
138
+ def inspect; end
139
+
140
+ sig { params(other: Object).returns(T::Boolean) }
141
+ def ==(other); end
142
+
143
+ sig { returns(Integer) }
144
+ def hash; end
121
145
  end
122
146
  end