riffer 0.36.0 → 0.37.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: 491260200757bf1d17b920f099012d771328fd333d46bb325f53dca863bcf204
4
- data.tar.gz: 072ffcdf47b2aa115a3c7743cb77d4f238d18b926f0a53eb6b45a28148b8b2be
3
+ metadata.gz: cf3c522a083d44f9aff259baf496cea4f6da7a160872b1e78a2f123693a19942
4
+ data.tar.gz: b3220efe62fcb3144fdc041f71c914baff02003b5f1aad3b4af285487986c673
5
5
  SHA512:
6
- metadata.gz: 97bf5aeed05fe9b591ae5a2bcf7c59d6990a46de1695fa4ff929823ead08b23372f35c4efb389a7e2f769a2a15dbad4dcb35bb1421e57c1fe5291216390b176c
7
- data.tar.gz: 421d381a7d8c0a1be0c017a2c347096fa452d48d512706c474e82b5d90097e245d9f7680ed6745c10aac31502cdfe47efc56ae885dbd9e4b52b3b7e2803b7c10
6
+ metadata.gz: 82ca97fe33585a833f6126837c9546ee137aa2ccc0259f732a7f634207e82f3fa0c4a4ec05f80274c73fefa9e234c27b63db87672df1198412c6b66a9884b564
7
+ data.tar.gz: b91541b19e44d4a02efbf10cd6bda8b3476fbf846f61e2cdabe19822fc1648542a2279ec4170e8dcc2ff462bc1419af552237e6f8e47e2748949139a5b53b9b2
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.36.0"
2
+ ".": "0.37.0"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.37.0](https://github.com/janeapp/riffer/compare/riffer/v0.36.0...riffer/v0.37.0) (2026-07-10)
9
+
10
+
11
+ ### Features
12
+
13
+ * **providers:** first-class provider registration API ([#353](https://github.com/janeapp/riffer/issues/353)) ([551d80b](https://github.com/janeapp/riffer/commit/551d80bf615de813629768156c6674d232877150))
14
+
8
15
  ## [0.36.0](https://github.com/janeapp/riffer/compare/riffer/v0.35.0...riffer/v0.36.0) (2026-07-03)
9
16
 
10
17
 
@@ -137,30 +137,15 @@ end
137
137
 
138
138
  ## Registering Your Provider
139
139
 
140
- Add your provider to the repository:
140
+ Register your provider under an identifier.
141
141
 
142
142
  ```ruby
143
- # In lib/riffer/providers/repository.rb or your own code
144
-
145
- Riffer::Providers::Repository::REPO[:my_provider] = -> { Riffer::Providers::MyProvider }
143
+ Riffer::Providers::Repository.register(:my_provider) { Riffer::Providers::MyProvider }
146
144
  ```
147
145
 
148
- Or create a custom repository:
146
+ The block resolves the provider class lazily, so it need not be loaded at registration time. Registration is idempotent — re-registering the same identifier replaces the previous factory — and a custom registration takes precedence over a built-in sharing the identifier, which lets you route an existing prefix (e.g. `openai`) through your own backend. Both `find` and `key_for` (used for pricing and observability keys) honor the registration. Remove one with `Riffer::Providers::Repository.unregister(:my_provider)`.
149
147
 
150
- ```ruby
151
- module MyApp
152
- module Providers
153
- def self.find(identifier)
154
- case identifier.to_sym
155
- when :my_provider
156
- Riffer::Providers::MyProvider
157
- else
158
- Riffer::Providers::Repository.find(identifier)
159
- end
160
- end
161
- end
162
- end
163
- ```
148
+ Register during application boot — from a Rails initializer or equivalent — before you start handling requests. The registry is not synchronized for concurrent mutation, so treat registration as a one-time setup step rather than something you do from a live request path.
164
149
 
165
150
  ## Using Your Provider
166
151
 
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
  # rbs_inline: enabled
3
3
 
4
- # Registry for finding provider classes by identifier.
4
+ # Resolves provider classes by identifier, combining the built-in REPO with
5
+ # consumer registrations added through +register+. Registration is not
6
+ # synchronized — register during boot, before concurrent generation begins.
5
7
  module Riffer::Providers::Repository
6
8
  extend self
7
9
 
10
+ # @rbs @registrations: Hash[Symbol, ^() -> singleton(Riffer::Providers::Base)]
8
11
  # @rbs @key_for: Hash[singleton(Riffer::Providers::Base), Symbol]?
9
12
 
10
13
  REPO = {
@@ -17,18 +20,55 @@ module Riffer::Providers::Repository
17
20
  mock: -> { Riffer::Providers::Mock }
18
21
  }.freeze #: Hash[Symbol, ^() -> singleton(Riffer::Providers::Base)]
19
22
 
20
- # Finds a provider class by identifier.
23
+ @registrations = {} #: Hash[Symbol, ^() -> singleton(Riffer::Providers::Base)]
24
+
25
+ # Registers a custom provider under +identifier+, resolved lazily by the block.
26
+ # Takes precedence over a built-in sharing the identifier.
27
+ #
28
+ # Riffer::Providers::Repository.register(:jane) { MyApp::JaneProvider }
29
+ #
30
+ # Raises Riffer::ArgumentError when called without a block.
31
+ #
32
+ #--
33
+ #: ((String | Symbol)) { () -> singleton(Riffer::Providers::Base) } -> void
34
+ def register(identifier, &factory)
35
+ raise Riffer::ArgumentError, "register requires a block returning a provider class" unless factory
36
+
37
+ @registrations[identifier.to_sym] = factory
38
+ @key_for = nil
39
+ end
40
+
41
+ # Removes a custom registration by identifier, leaving any built-in of the
42
+ # same name intact.
43
+ #--
44
+ #: ((String | Symbol)) -> void
45
+ def unregister(identifier)
46
+ @registrations.delete(identifier.to_sym)
47
+ @key_for = nil
48
+ end
49
+
50
+ # Finds a provider class by identifier, preferring a custom registration over
51
+ # a built-in of the same name.
21
52
  #
22
53
  #--
23
54
  #: ((String | Symbol)) -> singleton(Riffer::Providers::Base)?
24
55
  def find(identifier)
25
- REPO.fetch(identifier.to_sym, nil)&.call
56
+ key = identifier.to_sym
57
+ (@registrations[key] || REPO[key])&.call
26
58
  end
27
59
 
28
60
  # Returns the registry identifier for a provider class, or nil when unregistered.
29
61
  #--
30
62
  #: (singleton(Riffer::Providers::Base)) -> Symbol?
31
63
  def key_for(provider_class)
32
- (@key_for ||= REPO.to_h { |key, factory| [factory.call, key] })[provider_class]
64
+ (@key_for ||= build_key_index)[provider_class]
65
+ end
66
+
67
+ private
68
+
69
+ #--
70
+ #: () -> Hash[singleton(Riffer::Providers::Base), Symbol]
71
+ def build_key_index
72
+ REPO.merge(@registrations).to_h { |key, factory| [factory.call, key] }
33
73
  end
34
74
  end
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Riffer
5
- VERSION = "0.36.0" #: String
5
+ VERSION = "0.37.0" #: String
6
6
  end
@@ -1,12 +1,34 @@
1
1
  # Generated from lib/riffer/providers/repository.rb with RBS::Inline
2
2
 
3
- # Registry for finding provider classes by identifier.
3
+ # Resolves provider classes by identifier, combining the built-in REPO with
4
+ # consumer registrations added through +register+. Registration is not
5
+ # synchronized — register during boot, before concurrent generation begins.
4
6
  module Riffer::Providers::Repository
7
+ @registrations: Hash[Symbol, ^() -> singleton(Riffer::Providers::Base)]
8
+
5
9
  @key_for: Hash[singleton(Riffer::Providers::Base), Symbol]?
6
10
 
7
11
  REPO: Hash[Symbol, ^() -> singleton(Riffer::Providers::Base)]
8
12
 
9
- # Finds a provider class by identifier.
13
+ # Registers a custom provider under +identifier+, resolved lazily by the block.
14
+ # Takes precedence over a built-in sharing the identifier.
15
+ #
16
+ # Riffer::Providers::Repository.register(:jane) { MyApp::JaneProvider }
17
+ #
18
+ # Raises Riffer::ArgumentError when called without a block.
19
+ #
20
+ # --
21
+ # : ((String | Symbol)) { () -> singleton(Riffer::Providers::Base) } -> void
22
+ def register: (String | Symbol) { () -> singleton(Riffer::Providers::Base) } -> void
23
+
24
+ # Removes a custom registration by identifier, leaving any built-in of the
25
+ # same name intact.
26
+ # --
27
+ # : ((String | Symbol)) -> void
28
+ def unregister: (String | Symbol) -> void
29
+
30
+ # Finds a provider class by identifier, preferring a custom registration over
31
+ # a built-in of the same name.
10
32
  #
11
33
  # --
12
34
  # : ((String | Symbol)) -> singleton(Riffer::Providers::Base)?
@@ -16,4 +38,10 @@ module Riffer::Providers::Repository
16
38
  # --
17
39
  # : (singleton(Riffer::Providers::Base)) -> Symbol?
18
40
  def key_for: (singleton(Riffer::Providers::Base)) -> Symbol?
41
+
42
+ private
43
+
44
+ # --
45
+ # : () -> Hash[singleton(Riffer::Providers::Base), Symbol]
46
+ def build_key_index: () -> Hash[singleton(Riffer::Providers::Base), Symbol]
19
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riffer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.36.0
4
+ version: 0.37.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jake Bottrall
@@ -35,14 +35,14 @@ dependencies:
35
35
  requirements:
36
36
  - - "~>"
37
37
  - !ruby/object:Gem::Version
38
- version: 1.51.0
38
+ version: 1.55.0
39
39
  type: :development
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
42
42
  requirements:
43
43
  - - "~>"
44
44
  - !ruby/object:Gem::Version
45
- version: 1.51.0
45
+ version: 1.55.0
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: aws-sdk-bedrockruntime
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +108,7 @@ dependencies:
108
108
  version: '2.25'
109
109
  - - "<"
110
110
  - !ruby/object:Gem::Version
111
- version: '2.42'
111
+ version: '2.43'
112
112
  type: :development
113
113
  prerelease: false
114
114
  version_requirements: !ruby/object:Gem::Requirement
@@ -118,21 +118,21 @@ dependencies:
118
118
  version: '2.25'
119
119
  - - "<"
120
120
  - !ruby/object:Gem::Version
121
- version: '2.42'
121
+ version: '2.43'
122
122
  - !ruby/object:Gem::Dependency
123
123
  name: io-event
124
124
  requirement: !ruby/object:Gem::Requirement
125
125
  requirements:
126
126
  - - "<"
127
127
  - !ruby/object:Gem::Version
128
- version: '1.17'
128
+ version: '1.20'
129
129
  type: :development
130
130
  prerelease: false
131
131
  version_requirements: !ruby/object:Gem::Requirement
132
132
  requirements:
133
133
  - - "<"
134
134
  - !ruby/object:Gem::Version
135
- version: '1.17'
135
+ version: '1.20'
136
136
  - !ruby/object:Gem::Dependency
137
137
  name: minitest
138
138
  requirement: !ruby/object:Gem::Requirement