typed_cache 0.1.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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/LICENSE +201 -0
- data/README.md +168 -0
- data/examples.md +190 -0
- data/lib/typed_cache/backend.rb +16 -0
- data/lib/typed_cache/backends/active_support.rb +113 -0
- data/lib/typed_cache/backends/memory.rb +166 -0
- data/lib/typed_cache/backends.rb +34 -0
- data/lib/typed_cache/cache_builder.rb +77 -0
- data/lib/typed_cache/cache_key.rb +45 -0
- data/lib/typed_cache/cache_ref.rb +155 -0
- data/lib/typed_cache/clock.rb +23 -0
- data/lib/typed_cache/decorator.rb +12 -0
- data/lib/typed_cache/decorators.rb +35 -0
- data/lib/typed_cache/either.rb +121 -0
- data/lib/typed_cache/errors.rb +64 -0
- data/lib/typed_cache/instrumentation.rb +112 -0
- data/lib/typed_cache/maybe.rb +92 -0
- data/lib/typed_cache/namespace.rb +162 -0
- data/lib/typed_cache/registry.rb +55 -0
- data/lib/typed_cache/snapshot.rb +72 -0
- data/lib/typed_cache/store/instrumented.rb +83 -0
- data/lib/typed_cache/store.rb +152 -0
- data/lib/typed_cache/version.rb +5 -0
- data/lib/typed_cache.rb +58 -0
- data/sig/generated/typed_cache/backend.rbs +17 -0
- data/sig/generated/typed_cache/backends/active_support.rbs +56 -0
- data/sig/generated/typed_cache/backends/memory.rbs +95 -0
- data/sig/generated/typed_cache/backends.rbs +21 -0
- data/sig/generated/typed_cache/cache_builder.rbs +37 -0
- data/sig/generated/typed_cache/cache_key.rbs +33 -0
- data/sig/generated/typed_cache/cache_ref.rbs +91 -0
- data/sig/generated/typed_cache/clock.rbs +15 -0
- data/sig/generated/typed_cache/decorator.rbs +14 -0
- data/sig/generated/typed_cache/decorators.rbs +25 -0
- data/sig/generated/typed_cache/either.rbs +106 -0
- data/sig/generated/typed_cache/errors.rbs +51 -0
- data/sig/generated/typed_cache/instrumentation.rbs +30 -0
- data/sig/generated/typed_cache/maybe.rbs +85 -0
- data/sig/generated/typed_cache/namespace.rbs +130 -0
- data/sig/generated/typed_cache/registry.rbs +25 -0
- data/sig/generated/typed_cache/snapshot.rbs +50 -0
- data/sig/generated/typed_cache/store/instrumented.rbs +37 -0
- data/sig/generated/typed_cache/store.rbs +104 -0
- data/sig/generated/typed_cache/version.rbs +5 -0
- data/sig/generated/typed_cache.rbs +34 -0
- data/sig/handwritten/gems/zeitwerk/2.7/zeitwerk.rbs +9 -0
- data/typed_cache.gemspec +42 -0
- data.tar.gz.sig +0 -0
- metadata +228 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,106 @@
|
|
1
|
+
# Generated from lib/typed_cache/either.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
type either[out E, out R] = (Left[E] | Right[R]) & _Either[E, R]
|
5
|
+
|
6
|
+
module Either
|
7
|
+
include Kernel
|
8
|
+
|
9
|
+
# : [E] (E) -> either[E, bot]
|
10
|
+
def self.left: [E] (E) -> either[E, bot]
|
11
|
+
|
12
|
+
# : [R] (R) -> either[bot, R]
|
13
|
+
def self.right: [R] (R) -> either[bot, R]
|
14
|
+
|
15
|
+
# : [E, R] (E | R) -> either[E, R]
|
16
|
+
def self.wrap: [E, R] (E | R) -> either[E, R]
|
17
|
+
end
|
18
|
+
|
19
|
+
interface _Either[out E, out R]
|
20
|
+
def left?: () -> bool
|
21
|
+
|
22
|
+
def right?: () -> bool
|
23
|
+
|
24
|
+
def map: [T] () { (R) -> T } -> either[E, T]
|
25
|
+
|
26
|
+
def bind: [E2, R2] () { (R) -> either[E2, R2] } -> either[E | E2, R2]
|
27
|
+
|
28
|
+
def map_left: [F] () { (E) -> F } -> either[F, R]
|
29
|
+
|
30
|
+
def fold: [T, E, R] (^(E) -> T, ^(R) -> T) -> T
|
31
|
+
end
|
32
|
+
|
33
|
+
# @rbs generic out E
|
34
|
+
class Left[out E]
|
35
|
+
include _Either[E, bot]
|
36
|
+
|
37
|
+
attr_reader error: E
|
38
|
+
|
39
|
+
# : (E) -> void
|
40
|
+
def initialize: (E) -> void
|
41
|
+
|
42
|
+
# @rbs override
|
43
|
+
# : -> true
|
44
|
+
def left?: ...
|
45
|
+
|
46
|
+
# @rbs override
|
47
|
+
# : -> false
|
48
|
+
def right?: ...
|
49
|
+
|
50
|
+
# @rbs override
|
51
|
+
# : [T] () { (R) -> T } -> either[E, T]
|
52
|
+
def map: ...
|
53
|
+
|
54
|
+
# @rbs override
|
55
|
+
# : [E2, R2] () { (R) -> either[E2, R2] } -> either[E | E2, R2]
|
56
|
+
def bind: ...
|
57
|
+
|
58
|
+
# @rbs override
|
59
|
+
# : [F] () { (E) -> F } -> either[F, R]
|
60
|
+
def map_left: ...
|
61
|
+
|
62
|
+
# @rbs override
|
63
|
+
# : [T, E, R] (^(E) -> T, ^(R) -> T) -> T
|
64
|
+
def fold: ...
|
65
|
+
|
66
|
+
# : (Array[top]) -> ({ error: E })
|
67
|
+
def deconstruct_keys: (Array[top]) -> { error: E }
|
68
|
+
end
|
69
|
+
|
70
|
+
# @rbs generic out R
|
71
|
+
class Right[out R]
|
72
|
+
include _Either[bot, R]
|
73
|
+
|
74
|
+
attr_reader value: R
|
75
|
+
|
76
|
+
# : (R) -> void
|
77
|
+
def initialize: (R) -> void
|
78
|
+
|
79
|
+
# @rbs override
|
80
|
+
# : -> false
|
81
|
+
def left?: ...
|
82
|
+
|
83
|
+
# @rbs override
|
84
|
+
# : -> true
|
85
|
+
def right?: ...
|
86
|
+
|
87
|
+
# @rbs override
|
88
|
+
# : [T] () { (R) -> T } -> either[E, T]
|
89
|
+
def map: ...
|
90
|
+
|
91
|
+
# @rbs override
|
92
|
+
# : [E2, R2] () { (R) -> either[E2, R2] } -> either[E | E2, R2]
|
93
|
+
def bind: ...
|
94
|
+
|
95
|
+
# @rbs override
|
96
|
+
# : [F] () { (E) -> F } -> either[F, R]
|
97
|
+
def map_left: ...
|
98
|
+
|
99
|
+
# @rbs override
|
100
|
+
# : [T, E, R] (^(E) -> T, ^(R) -> T) -> T
|
101
|
+
def fold: ...
|
102
|
+
|
103
|
+
# : (Array[top]) -> ({ value: R })
|
104
|
+
def deconstruct_keys: (Array[top]) -> { value: R }
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Generated from lib/typed_cache/errors.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
# Base error class for TypedCache operations
|
5
|
+
class Error < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
# Store operation errors (network, I/O, etc.)
|
9
|
+
class StoreError < Error
|
10
|
+
attr_reader operation: untyped
|
11
|
+
|
12
|
+
attr_reader key: untyped
|
13
|
+
|
14
|
+
attr_reader original_error: untyped
|
15
|
+
|
16
|
+
# @rbs (Symbol, String, String, Exception?) -> void
|
17
|
+
def initialize: (Symbol, String, String, Exception?) -> void
|
18
|
+
|
19
|
+
# @rbs () -> String
|
20
|
+
def detailed_message: () -> String
|
21
|
+
|
22
|
+
# @rbs () -> bool
|
23
|
+
def has_cause?: () -> bool
|
24
|
+
end
|
25
|
+
|
26
|
+
# Type safety violations
|
27
|
+
class TypeError < Error
|
28
|
+
attr_reader expected_type: untyped
|
29
|
+
|
30
|
+
attr_reader actual_type: untyped
|
31
|
+
|
32
|
+
attr_reader value: untyped
|
33
|
+
|
34
|
+
# @rbs (String, String, untyped, String) -> void
|
35
|
+
def initialize: (String, String, untyped, String) -> void
|
36
|
+
|
37
|
+
# @rbs () -> String
|
38
|
+
def type_mismatch_message: () -> String
|
39
|
+
end
|
40
|
+
|
41
|
+
# Cache miss (when expecting a value to exist)
|
42
|
+
class CacheMissError < Error
|
43
|
+
attr_reader key: untyped
|
44
|
+
|
45
|
+
# @rbs (CacheKey) -> void
|
46
|
+
def initialize: (CacheKey) -> void
|
47
|
+
|
48
|
+
# @rbs () -> bool
|
49
|
+
def cache_miss?: () -> bool
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Generated from lib/typed_cache/instrumentation.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
# Instrumentation hooks for ActiveSupport::Notifications integration
|
5
|
+
# All instrumentation is explicit and opt-in - no automatic behavior
|
6
|
+
module Instrumentation
|
7
|
+
type config = TypedCache::_TypedCacheInstrumentationConfig
|
8
|
+
|
9
|
+
# @rbs () -> config
|
10
|
+
def self.config: () -> config
|
11
|
+
|
12
|
+
# Check if ActiveSupport::Notifications is available
|
13
|
+
# @rbs () -> bool
|
14
|
+
def self.notifications_available?: () -> bool
|
15
|
+
|
16
|
+
# Main instrumentation method
|
17
|
+
# : [T] (String, String, String, Hash[Symbol, untyped]) { -> T } -> T
|
18
|
+
def self.instrument: [T] (String, String, String, Hash[Symbol, untyped]) { () -> T } -> T
|
19
|
+
|
20
|
+
# Cross-platform current time helper (uses Time.current when available)
|
21
|
+
# : -> Time
|
22
|
+
private def self.current_time: () -> Time
|
23
|
+
|
24
|
+
# @rbs (String, String, Time) -> Hash[Symbol, untyped]
|
25
|
+
private def self.base_payload: (String, String, Time) -> Hash[Symbol, untyped]
|
26
|
+
|
27
|
+
# @rbs (Either[StandardError, Snapshot]) -> [bool, Hash[Symbol, untyped]]
|
28
|
+
private def self.extract_result_metadata: (Either[StandardError, Snapshot]) -> [ bool, Hash[Symbol, untyped] ]
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Generated from lib/typed_cache/maybe.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
type maybe[T] = (Nothing | Some[T]) & _Maybe[T]
|
5
|
+
|
6
|
+
module Maybe
|
7
|
+
include Kernel
|
8
|
+
|
9
|
+
# : [V](V) -> maybe[V]
|
10
|
+
def self.some: [V] (V) -> maybe[V]
|
11
|
+
|
12
|
+
# : -> maybe[bot]
|
13
|
+
def self.none: () -> maybe[bot]
|
14
|
+
|
15
|
+
# : [V](V? | maybe[V]) -> maybe[V]
|
16
|
+
def self.wrap: [V] (V? | maybe[V]) -> maybe[V]
|
17
|
+
|
18
|
+
alias self.[] self.some
|
19
|
+
end
|
20
|
+
|
21
|
+
interface _Maybe[out V]
|
22
|
+
def some?: () -> bool
|
23
|
+
|
24
|
+
def nothing?: () -> bool
|
25
|
+
|
26
|
+
def map: [T] () { (V) -> T } -> maybe[T]
|
27
|
+
|
28
|
+
def bind: [T] () { (V) -> maybe[T] } -> maybe[T]
|
29
|
+
|
30
|
+
alias flat_map bind
|
31
|
+
end
|
32
|
+
|
33
|
+
# @rbs generic out V
|
34
|
+
class Some[out V]
|
35
|
+
include _Maybe[V]
|
36
|
+
|
37
|
+
attr_reader value: V
|
38
|
+
|
39
|
+
# : (V) -> void
|
40
|
+
def initialize: (V) -> void
|
41
|
+
|
42
|
+
# @rbs override
|
43
|
+
# : -> TrueClass
|
44
|
+
def some?: ...
|
45
|
+
|
46
|
+
# @rbs override
|
47
|
+
# : -> FalseClass
|
48
|
+
def nothing?: ...
|
49
|
+
|
50
|
+
# @rbs override
|
51
|
+
# : [T] () { (V) -> T } -> maybe[T]
|
52
|
+
def map: ...
|
53
|
+
|
54
|
+
# @rbs override
|
55
|
+
# : [T] () { (V) -> maybe[T] } -> maybe[T]
|
56
|
+
def bind: ...
|
57
|
+
|
58
|
+
alias flat_map bind
|
59
|
+
|
60
|
+
# : (Array[top]) -> ({ value: V })
|
61
|
+
def deconstruct_keys: (Array[top]) -> { value: V }
|
62
|
+
end
|
63
|
+
|
64
|
+
class Nothing
|
65
|
+
include _Maybe[bot]
|
66
|
+
|
67
|
+
# @rbs override
|
68
|
+
# : -> FalseClass
|
69
|
+
def some?: ...
|
70
|
+
|
71
|
+
# @rbs override
|
72
|
+
# : -> TrueClass
|
73
|
+
def nothing?: ...
|
74
|
+
|
75
|
+
# @rbs override
|
76
|
+
# : [T] () { (V) -> T } -> maybe[T]
|
77
|
+
def map: ...
|
78
|
+
|
79
|
+
# @rbs override
|
80
|
+
# : [T] () { (V) -> maybe[T] } -> maybe[T]
|
81
|
+
def bind: ...
|
82
|
+
|
83
|
+
alias flat_map bind
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# Generated from lib/typed_cache/namespace.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
# Provides a type-safe, composable namespace abstraction for cache keys.
|
5
|
+
#
|
6
|
+
# The Namespace class allows you to create hierarchical namespaces for cache keys,
|
7
|
+
# ensuring that keys are properly scoped and collisions are avoided. Each Namespace
|
8
|
+
# instance can generate cache keys (via #key), create nested namespaces (via #nested),
|
9
|
+
# and traverse to parent namespaces (via #parent_namespace).
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
# ns = TypedCache::Namespace.at("users")
|
13
|
+
# ns.key("123") # => #<TypedCache::CacheKey namespace=users key=123>
|
14
|
+
# ns2 = ns.nested("sessions")
|
15
|
+
# ns2.key("abc") # => #<TypedCache::CacheKey namespace=users:sessions key=abc>
|
16
|
+
#
|
17
|
+
# Namespaces are composable and immutable. The key factory can be customized for advanced use cases.
|
18
|
+
class Namespace
|
19
|
+
# Returns a new Namespace instance rooted at the given namespace string.
|
20
|
+
#
|
21
|
+
# @param namespace [String] the root namespace
|
22
|
+
# @return [Namespace] a new Namespace instance at the given root
|
23
|
+
#
|
24
|
+
# Example:
|
25
|
+
# TypedCache::Namespace.at("users") # => #<TypedCache::Namespace namespace=users>
|
26
|
+
#
|
27
|
+
# The returned Namespace can be further nested or used to generate cache keys.
|
28
|
+
#
|
29
|
+
# @rbs (String) -> Namespace
|
30
|
+
def self.at: (String) -> Namespace
|
31
|
+
|
32
|
+
# Returns the root Namespace instance (with an empty namespace).
|
33
|
+
#
|
34
|
+
# @return [Namespace] the root Namespace
|
35
|
+
#
|
36
|
+
# Example:
|
37
|
+
# TypedCache::Namespace.root # => #<TypedCache::Namespace namespace=>
|
38
|
+
#
|
39
|
+
# The root namespace is useful as a starting point for building nested namespaces.
|
40
|
+
#
|
41
|
+
# @rbs () -> Namespace
|
42
|
+
def self.root: () -> Namespace
|
43
|
+
|
44
|
+
# Initializes a new Namespace instance with the given namespace string and key factory.
|
45
|
+
#
|
46
|
+
# @param namespace [String] the namespace string for this instance
|
47
|
+
# @param key_factory [Proc] a block that creates CacheKey instances from key strings
|
48
|
+
# @yield [key] the key string to create a CacheKey from
|
49
|
+
# @yieldreturn [CacheKey] the created cache key
|
50
|
+
#
|
51
|
+
# Example:
|
52
|
+
# Namespace.new("users") { |key| CacheKey.new("users", key) }
|
53
|
+
#
|
54
|
+
# @rbs (String) { (Namespace, String) -> CacheKey } -> void
|
55
|
+
def initialize: (String) { (Namespace, String) -> CacheKey } -> void
|
56
|
+
|
57
|
+
# Creates a nested namespace by appending the given namespace to the current one.
|
58
|
+
#
|
59
|
+
# @param namespace [String] the namespace to append
|
60
|
+
# @param key_factory [Proc, nil] optional custom key factory for the nested namespace
|
61
|
+
# @return [Namespace] a new Namespace instance with the combined namespace
|
62
|
+
#
|
63
|
+
# Example:
|
64
|
+
# ns = Namespace.at("users")
|
65
|
+
# ns.nested("sessions") # => #<TypedCache::Namespace namespace=users:sessions>
|
66
|
+
#
|
67
|
+
# If no key_factory is provided, the parent's key factory is inherited.
|
68
|
+
#
|
69
|
+
# @rbs (String) ?{ (Namespace, String) -> CacheKey } -> Namespace
|
70
|
+
def nested: (String) ?{ (Namespace, String) -> CacheKey } -> Namespace
|
71
|
+
|
72
|
+
# Returns the parent namespace by removing the last namespace segment.
|
73
|
+
#
|
74
|
+
# @return [Namespace] the parent namespace, or self if already at root
|
75
|
+
#
|
76
|
+
# Example:
|
77
|
+
# ns = Namespace.at("users:sessions")
|
78
|
+
# ns.parent_namespace # => #<TypedCache::Namespace namespace=users>
|
79
|
+
#
|
80
|
+
# For root namespaces (empty string), returns self.
|
81
|
+
#
|
82
|
+
# @rbs () -> Namespace
|
83
|
+
def parent_namespace: () -> Namespace
|
84
|
+
|
85
|
+
# Creates a cache key using the namespace's key factory.
|
86
|
+
#
|
87
|
+
# @param key [String] the key string to create a cache key from
|
88
|
+
# @return [CacheKey] the created cache key
|
89
|
+
#
|
90
|
+
# Example:
|
91
|
+
# ns = Namespace.at("users")
|
92
|
+
# ns.key("123") # => #<TypedCache::CacheKey namespace=users key=123>
|
93
|
+
#
|
94
|
+
# @rbs (String) -> CacheKey
|
95
|
+
def key: (String) -> CacheKey
|
96
|
+
|
97
|
+
# @rbs () -> bool
|
98
|
+
def root?: () -> bool
|
99
|
+
|
100
|
+
# Returns the namespace string representation.
|
101
|
+
#
|
102
|
+
# @return [String] the namespace string
|
103
|
+
#
|
104
|
+
# Example:
|
105
|
+
# ns = Namespace.at("users:sessions")
|
106
|
+
# ns.to_s # => "users:sessions"
|
107
|
+
#
|
108
|
+
# @rbs () -> String
|
109
|
+
def to_s: () -> String
|
110
|
+
|
111
|
+
# Returns a string representation of the Namespace instance for debugging.
|
112
|
+
#
|
113
|
+
# @return [String] a debug-friendly string representation
|
114
|
+
#
|
115
|
+
# Example:
|
116
|
+
# ns = Namespace.at("users")
|
117
|
+
# ns.inspect # => "#<TypedCache::Namespace namespace=users>"
|
118
|
+
#
|
119
|
+
# @rbs () -> String
|
120
|
+
def inspect: () -> String
|
121
|
+
|
122
|
+
# @rbs () -> Integer
|
123
|
+
def hash: () -> Integer
|
124
|
+
|
125
|
+
# @rbs (Object) -> bool
|
126
|
+
def ==: (Object) -> bool
|
127
|
+
|
128
|
+
alias eql? ==
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Generated from lib/typed_cache/registry.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
# Generic registry for managing class-based factories
|
5
|
+
# @rbs generic T
|
6
|
+
class Registry[T]
|
7
|
+
# @rbs (String, Hash[Symbol, Class[T]]) -> void
|
8
|
+
def initialize: (String, Hash[Symbol, Class[T]]) -> void
|
9
|
+
|
10
|
+
# @rbs (Symbol, *untyped, **untyped) -> either[Error, T]
|
11
|
+
def resolve: (Symbol, *untyped, **untyped) -> either[Error, T]
|
12
|
+
|
13
|
+
# @rbs (Symbol) -> maybe[Class[T]]
|
14
|
+
def find: (Symbol) -> maybe[Class[T]]
|
15
|
+
|
16
|
+
# @rbs (Symbol, Class[T]) -> either[Error, void]
|
17
|
+
def register: (Symbol, Class[T]) -> either[Error, void]
|
18
|
+
|
19
|
+
# @rbs () -> Array[Symbol]
|
20
|
+
def available: () -> Array[Symbol]
|
21
|
+
|
22
|
+
# @rbs (Symbol) -> bool
|
23
|
+
def registered?: (Symbol) -> bool
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Generated from lib/typed_cache/snapshot.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
# Immutable snapshot of a cached value with metadata about its source and age
|
5
|
+
# @rbs generic V
|
6
|
+
class Snapshot[V]
|
7
|
+
attr_reader value: V
|
8
|
+
|
9
|
+
attr_reader retrieved_at: Time
|
10
|
+
|
11
|
+
attr_reader source: Symbol
|
12
|
+
|
13
|
+
# : (V, source: Symbol, retrieved_at: Time) -> void
|
14
|
+
def initialize: (V, source: Symbol, retrieved_at: Time) -> void
|
15
|
+
|
16
|
+
# Age of the snapshot in seconds
|
17
|
+
# : -> Float
|
18
|
+
def age: () -> Float
|
19
|
+
|
20
|
+
# Whether this value came from cache
|
21
|
+
# : -> bool
|
22
|
+
def from_cache?: () -> bool
|
23
|
+
|
24
|
+
# Whether this value was freshly computed
|
25
|
+
# : -> bool
|
26
|
+
def computed?: () -> bool
|
27
|
+
|
28
|
+
# Whether this value was updated
|
29
|
+
# : -> bool
|
30
|
+
def updated?: () -> bool
|
31
|
+
|
32
|
+
# Map over the value while preserving snapshot metadata
|
33
|
+
# : [R] () { (V) -> R } -> Snapshot[R]
|
34
|
+
def map: [R] () { (V) -> R } -> Snapshot[R]
|
35
|
+
|
36
|
+
# Bind over the value with Either error handling
|
37
|
+
# : [R] () { (V) -> either[Error, R] } -> either[Error, Snapshot[R]]
|
38
|
+
def bind: [R] () { (V) -> either[Error, R] } -> either[Error, Snapshot[R]]
|
39
|
+
|
40
|
+
alias flat_map bind
|
41
|
+
|
42
|
+
# Creates a snapshot for a computed value
|
43
|
+
# : [V] (V) -> Snapshot[V]
|
44
|
+
def self.computed: [V] (V) -> Snapshot[V]
|
45
|
+
|
46
|
+
# Creates a snapshot for an updated value
|
47
|
+
# : [V] (V) -> Snapshot[V]
|
48
|
+
def self.updated: [V] (V) -> Snapshot[V]
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Generated from lib/typed_cache/store/instrumented.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
# Decorator that adds instrumentation to any Store implementation
|
5
|
+
# This decorator can wrap any store to add ActiveSupport::Notifications
|
6
|
+
# @rbs generic V
|
7
|
+
class Store::Instrumented[V]
|
8
|
+
include Decorator[V]
|
9
|
+
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
attr_reader store: TypedCache::Store[V]
|
13
|
+
|
14
|
+
# @rbs (Symbol, ?operation: String) ?{ (*untyped, **untyped) -> String } -> void
|
15
|
+
private def self.instrument: (Symbol, ?operation: String) ?{ (*untyped, **untyped) -> String } -> void
|
16
|
+
|
17
|
+
# : (TypedCache::Store[V]) -> void
|
18
|
+
def initialize: (TypedCache::Store[V]) -> void
|
19
|
+
|
20
|
+
# @rbs override
|
21
|
+
# : -> String
|
22
|
+
def namespace: ...
|
23
|
+
|
24
|
+
# @rbs override
|
25
|
+
# : -> String
|
26
|
+
def store_type: ...
|
27
|
+
|
28
|
+
# @rbs override
|
29
|
+
# : (cache_key) -> either[Error, CacheRef[V]]
|
30
|
+
def ref: ...
|
31
|
+
|
32
|
+
# Additional methods that might exist on the wrapped store
|
33
|
+
def respond_to_missing?: (untyped method_name, ?untyped include_private) -> untyped
|
34
|
+
|
35
|
+
def method_missing: (untyped method_name, *untyped args) ?{ (?) -> untyped } -> untyped
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# Generated from lib/typed_cache/store.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
# Generic interface for type-safe cache storage implementations
|
5
|
+
# All stores are assumed to handle namespacing internally
|
6
|
+
#
|
7
|
+
# This interface follows the Command-Query Separation principle:
|
8
|
+
# - Commands (set, delete, clear) perform actions and may return results
|
9
|
+
# - Queries (get, key?, fetch) ask questions without side effects
|
10
|
+
#
|
11
|
+
# @rbs generic V
|
12
|
+
module Store[V]
|
13
|
+
type cache_key = String | CacheKey
|
14
|
+
|
15
|
+
interface _Store[V]
|
16
|
+
def get: (cache_key) -> either[Error, Snapshot[V]]
|
17
|
+
|
18
|
+
def ref: (cache_key) -> CacheRef[V]
|
19
|
+
|
20
|
+
def set: (cache_key, V) -> either[Error, Snapshot[V]]
|
21
|
+
|
22
|
+
def delete: (cache_key) -> either[Error, Snapshot[V]]
|
23
|
+
|
24
|
+
def key?: (cache_key) -> bool
|
25
|
+
|
26
|
+
def clear: () -> maybe[Error]
|
27
|
+
|
28
|
+
def fetch: (cache_key) { () -> V } -> either[Error, Snapshot[V]]
|
29
|
+
|
30
|
+
def namespace: () -> Namespace
|
31
|
+
|
32
|
+
def with_namespace: (Namespace) -> Store[V]
|
33
|
+
|
34
|
+
def store_type: () -> String
|
35
|
+
end
|
36
|
+
|
37
|
+
include _Store[V]
|
38
|
+
|
39
|
+
interface _Decorator[V]
|
40
|
+
def initialize: (Store[V]) -> void
|
41
|
+
end
|
42
|
+
|
43
|
+
# @rbs (Store[V]) -> void
|
44
|
+
def initialize_copy: (Store[V]) -> void
|
45
|
+
|
46
|
+
# Retrieves a value from the cache
|
47
|
+
# @rbs (cache_key) -> either[Error, Snapshot[V]]
|
48
|
+
def get: (cache_key) -> either[Error, Snapshot[V]]
|
49
|
+
|
50
|
+
# Retrieves a cache reference for a key
|
51
|
+
# @rbs (cache_key) -> CacheRef[V]
|
52
|
+
def ref: (cache_key) -> CacheRef[V]
|
53
|
+
|
54
|
+
# Stores a value in the cache
|
55
|
+
# @rbs (cache_key, V) -> either[Error, Snapshot[V]]
|
56
|
+
def set: (cache_key, V) -> either[Error, Snapshot[V]]
|
57
|
+
|
58
|
+
# Removes a value from the cache, returning the removed value
|
59
|
+
# @rbs (cache_key) -> either[Error, Snapshot[V]]
|
60
|
+
def delete: (cache_key) -> either[Error, Snapshot[V]]
|
61
|
+
|
62
|
+
# Checks if a key exists in the cache (query operation)
|
63
|
+
# @rbs (cache_key) -> bool
|
64
|
+
def key?: (cache_key) -> bool
|
65
|
+
|
66
|
+
# Clears all values from the cache namespace (command operation)
|
67
|
+
# @rbs () -> maybe[Error]
|
68
|
+
def clear: () -> maybe[Error]
|
69
|
+
|
70
|
+
# Fetches a value from cache, computing and storing it if not found
|
71
|
+
# This is an atomic operation that combines get and set
|
72
|
+
# @rbs (cache_key) { () -> V } -> either[Error, Snapshot[V]]
|
73
|
+
def fetch: (cache_key) { () -> V } -> either[Error, Snapshot[V]]
|
74
|
+
|
75
|
+
# Returns the namespace for this store (for instrumentation/debugging)
|
76
|
+
# @rbs () -> Namespace
|
77
|
+
def namespace: () -> Namespace
|
78
|
+
|
79
|
+
# Accepts a String segment or a fully-formed Namespace and returns a cloned
|
80
|
+
# store scoped to that namespace.
|
81
|
+
# @rbs (Namespace | String) -> Store[V]
|
82
|
+
def with_namespace: (Namespace | String) -> Store[V]
|
83
|
+
|
84
|
+
# Returns the store type identifier for instrumentation/debugging
|
85
|
+
# @rbs () -> String
|
86
|
+
def store_type: () -> String
|
87
|
+
|
88
|
+
attr_writer namespace: Namespace
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# : (String) -> String
|
93
|
+
def snake_case: (String) -> String
|
94
|
+
|
95
|
+
# : (cache_key) -> CacheKey
|
96
|
+
def namespaced_key: (cache_key) -> CacheKey
|
97
|
+
end
|
98
|
+
|
99
|
+
type backend[V] = Store::_Store[V]
|
100
|
+
|
101
|
+
type decorator[V] = backend[V] & Store::_Decorator[V]
|
102
|
+
|
103
|
+
type store[V] = backend[V] | decorator[V]
|
104
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Generated from lib/typed_cache.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
extend Dry::Configurable
|
5
|
+
|
6
|
+
interface _TypedCacheInstrumentationConfig
|
7
|
+
def enabled: () -> bool
|
8
|
+
|
9
|
+
def namespace: () -> String
|
10
|
+
end
|
11
|
+
|
12
|
+
interface _TypedCacheConfig
|
13
|
+
def default_namespace: () -> String
|
14
|
+
|
15
|
+
def instrumentation: () -> _TypedCacheInstrumentationConfig
|
16
|
+
end
|
17
|
+
|
18
|
+
type typed_cache_config = _TypedCacheConfig
|
19
|
+
|
20
|
+
# Returns a CacheBuilder with the fluent interface
|
21
|
+
# @rbs [V] () -> CacheBuilder[V]
|
22
|
+
def self.builder: [V] () -> CacheBuilder[V]
|
23
|
+
|
24
|
+
def config: () -> _TypedCacheConfig
|
25
|
+
|
26
|
+
# @rbs () -> singleton(Instrumentation)
|
27
|
+
def self.instrumentation: () -> singleton(Instrumentation)
|
28
|
+
|
29
|
+
# @rbs () -> Registry[backend[untyped]]
|
30
|
+
def self.backends: () -> Registry[backend[untyped]]
|
31
|
+
|
32
|
+
# @rbs () -> Register[decorator[untyped]]
|
33
|
+
def self.decorators: () -> Register[decorator[untyped]]
|
34
|
+
end
|