zen-service 2.2.0 → 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12dcff33c206c08f710f8cedf505f663387054b22aa6429556b20c47eac6b410
4
- data.tar.gz: b314175b5a9a5634480ac0c4fbec0777fa895e68687eedbaad8382f1b26600fe
3
+ metadata.gz: 207425486ecb408db660e845768e30e9cd19aa3ed1d6a7214d41fc0eecd46590
4
+ data.tar.gz: 74787fb37ce4bc2e6d7c139e7ca7b245c25fcafd6711a1aba434c0e681007b9b
5
5
  SHA512:
6
- metadata.gz: 3bb64af64bf4641e01b686bf4b8bda93e5efcd8188d1ed6d1a864c74e0f2d916b03383345476c0aa1a860b3bae9ba6fbf370f6e309905d7ef5cb1186fd561b7d
7
- data.tar.gz: b2678a54e99637e8d1706a6ccd913346d9e64d7ea0ef46e2c7e5637683844ab21220b6c1422601fc8466178358377e6da092cc0320cc5f6e427052b5e1b786f1
6
+ metadata.gz: 4bc0fe9454e82c5b49f9ab87e3812e002691002d1476b9258417fa12ddae5419ea3621de952c821b27716078e9008745acf02e00946a5538570dd89c3a020972
7
+ data.tar.gz: e26b152b882e1fc74ef35a99644bcc3b976c8710eb8c5833b5393edf0843f190006a019c157ba2958a082d03cedcf4c989fd2b6d5788c0bb27f36d0e9f63391f
@@ -12,7 +12,8 @@ The entire gem is built around `Zen::Service::Plugins` - a dynamic plugin regist
12
12
 
13
13
  - Plugins auto-register using `extend Zen::Service::Plugins::Plugin` (converts module name to snake_case key)
14
14
  - Services use plugins via `use :plugin_name, **options`
15
- - Plugin lifecycle: `used(service_class)` → includes module → `configure(service_class)` if defined
15
+ - Plugin lifecycle (first use): `used(service_class)` → includes module → `configure(service_class)` if defined
16
+ - Plugin reconfiguration (ancestor already used): only `configure(service_class)` is called, module not re-included
16
17
  - See [plugin.rb](lib/zen/service/plugins/plugin.rb) for the DSL: `register_as`, `default_options`, `service_extension`
17
18
 
18
19
  ### Core Plugins Architecture
@@ -97,6 +98,13 @@ end
97
98
  - Use `default_options foo: 5` in plugin definition
98
99
  - Access via `self.class.plugins[:plugin_name].options[:foo]`
99
100
  - Options merge with defaults when using plugin
101
+ - Blocks passed to `use` are stored in `reflection.block`, separate from options (not polluting options hash)
102
+
103
+ ### Plugin Inheritance & Reconfiguration
104
+
105
+ - When a child class uses a plugin already used by an ancestor, only `configure` callback is invoked (not `used`)
106
+ - This allows child classes to reconfigure plugin behavior without re-including the module
107
+ - Example: `BaseService` uses `:persisted_result` with default options, `ChildService` can reconfigure with different options
100
108
 
101
109
  ### Inheritance Behavior
102
110
 
data/README.md CHANGED
@@ -116,6 +116,26 @@ However, `zen-service` still provides a couple of helpfull plugins out-of-the-bo
116
116
  end
117
117
  ```
118
118
 
119
+ #### Plugin Lifecycle
120
+
121
+ When using a plugin on a service class:
122
+
123
+ - If the plugin is used for the first time, both `used` and `configure` callbacks are invoked
124
+ - If the plugin was already used by an ancestor class, only the `configure` callback is invoked,
125
+ allowing reconfiguration without re-including the module
126
+
127
+ This design allows child classes to customize plugin behavior inherited from parent classes:
128
+
129
+ ```rb
130
+ class BaseService < Zen::Service
131
+ use :persisted_result, call_unless_called: false
132
+ end
133
+
134
+ class ChildService < BaseService
135
+ use :persisted_result, call_unless_called: true # Only reconfigures, doesn't re-include
136
+ end
137
+ ```
138
+
119
139
  Bellow you can see sample implementation of a plugin that transforms resulting objects
120
140
  to camel-case notation (relying on ActiveSupport's core extensions)
121
141
 
@@ -3,7 +3,7 @@
3
3
  module Zen
4
4
  module Service::Plugins
5
5
  module Pluggable
6
- Reflection = Struct.new(:extension, :options)
6
+ Reflection = Struct.new(:extension, :options, :block)
7
7
 
8
8
  def use(name, **opts, &block)
9
9
  extension = Service::Plugins.fetch(name)
@@ -11,7 +11,7 @@ module Zen
11
11
  defaults = extension.config[:default_options]
12
12
  opts = defaults.merge(opts) unless defaults.nil?
13
13
 
14
- if service_plugins.key?(name)
14
+ if plugins.key?(name)
15
15
  extension.configure(self, **opts, &block) if extension.respond_to?(:configure)
16
16
  return extension
17
17
  end
@@ -45,7 +45,7 @@ module Zen
45
45
  extension.used(self, **opts, &block) if extension.respond_to?(:used)
46
46
  extension.configure(self, **opts, &block) if extension.respond_to?(:configure)
47
47
 
48
- service_plugins[name] = Reflection.new(extension, opts.merge(block:))
48
+ service_plugins[name] = Reflection.new(extension, opts, block)
49
49
 
50
50
  extension
51
51
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Zen
4
4
  class Service
5
- VERSION = "2.2.0"
5
+ VERSION = "2.2.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zen-service
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Kuzko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-12-28 00:00:00.000000000 Z
11
+ date: 2025-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry