event_engine-subscribers 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +110 -0
- data/Rakefile +9 -0
- data/app/assets/stylesheets/event_engine/subscribers/application.css +15 -0
- data/app/jobs/event_engine/subscribers/application_job.rb +6 -0
- data/app/jobs/event_engine/subscribers/dispatch_subscribers_job.rb +18 -0
- data/app/views/layouts/event_engine/subscribers/application.html.erb +17 -0
- data/lib/event_engine/subscribers/base.rb +34 -0
- data/lib/event_engine/subscribers/engine.rb +18 -0
- data/lib/event_engine/subscribers/processor.rb +26 -0
- data/lib/event_engine/subscribers/reference/guide.md +25 -0
- data/lib/event_engine/subscribers/reference.rb +19 -0
- data/lib/event_engine/subscribers/registry.rb +39 -0
- data/lib/event_engine/subscribers/the_local/agents/event_engine-subscribers-info.md +33 -0
- data/lib/event_engine/subscribers/the_local/agents/event_engine-subscribers-install.md +33 -0
- data/lib/event_engine/subscribers/the_local/agents/event_engine-subscribers-operate.md +33 -0
- data/lib/event_engine/subscribers/the_local.rb +48 -0
- data/lib/event_engine/subscribers/version.rb +5 -0
- data/lib/event_engine/subscribers.rb +10 -0
- data/lib/tasks/event_engine/subscribers_tasks.rake +4 -0
- metadata +126 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 62103c19fc7deee30fcd6d9e8aa1da8057d749557282779ce20a13fe8f24cad1
|
|
4
|
+
data.tar.gz: ef29545f420f28462eb3b4f071b3f8d313938624a62f15da40587b0886000254
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: e2ce9d39d1413720a051e21a38a48dfc31e6febc218518ea5a6c59703254b5791d57467a7ad2ce3d84f240592676d0ccf5de59d9374c42b07eff2e528b7e611b
|
|
7
|
+
data.tar.gz: 5371e6ef6c5bfae242ffee5bc8a38889a92d4417e7d664ac7cca1bdcbdba3fb66c0525162b4ef1572e055b1f03a5c34296125982c945178ffcfcfbfae2995645
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright tylercschneider
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# EventEngine::Subscribers
|
|
2
|
+
|
|
3
|
+
The **subscriber layer** of the [EventEngine](https://github.com/DYB-Development) pipeline.
|
|
4
|
+
|
|
5
|
+
EventEngine is a schema-first event pipeline. Events are declared with
|
|
6
|
+
[`event_engine-event_definition`](https://github.com/DYB-Development/event_engine-event_definition),
|
|
7
|
+
compiled into a committed catalog, and emitted through the
|
|
8
|
+
[`event_engine`](https://github.com/DYB-Development/event_engine) runtime. The runtime
|
|
9
|
+
resolves each event to a **processor** by name, using the host's rules file.
|
|
10
|
+
|
|
11
|
+
This gem is one of those processors. It runs the subscribers you write in your app —
|
|
12
|
+
either synchronously or in a background job.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
gem "event_engine-subscribers"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
It registers itself at boot as the `:inline` and `:background` processors. **You write
|
|
21
|
+
no wiring.**
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### 1. Write a subscriber
|
|
26
|
+
|
|
27
|
+
Subclass `Base`, declare the event, implement `#handle`. Declaring the subscription
|
|
28
|
+
self-registers the class, so there is nothing else to wire.
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
class SendWelcomeEmail < EventEngine::Subscribers::Base
|
|
32
|
+
subscribes_to :lead_created
|
|
33
|
+
|
|
34
|
+
def handle(event)
|
|
35
|
+
UserMailer.welcome(event.payload[:email]).deliver_later
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`event` is the `EventEngine::Event` the runtime built — `event_name`, `payload`,
|
|
41
|
+
`metadata`, `occurred_at` and the rest of the envelope.
|
|
42
|
+
|
|
43
|
+
Several subscribers may subscribe to the same event; each one's `#handle` is called.
|
|
44
|
+
|
|
45
|
+
### 2. Route the event to this gem
|
|
46
|
+
|
|
47
|
+
In your app's `config/event_rules.yml`, name `inline` or `background` for the event:
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
events:
|
|
51
|
+
lead_created: inline # run subscribers synchronously, during emit
|
|
52
|
+
lead_converted: background # enqueue a job and return immediately
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
That is the whole configuration.
|
|
56
|
+
|
|
57
|
+
| rule | what happens |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `inline` | every subscriber for the event runs synchronously inside `emit` |
|
|
60
|
+
| `background` | `DispatchSubscribersJob` is enqueued; subscribers run in a worker |
|
|
61
|
+
|
|
62
|
+
Choose `background` when the work is slow or failure-tolerant, `inline` when the
|
|
63
|
+
caller depends on it having happened.
|
|
64
|
+
|
|
65
|
+
### 3. Emit
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
MarketingEvents.lead_created(lead: lead)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Nothing else is needed — the runtime resolves the rule, finds this gem's processor,
|
|
72
|
+
and your subscribers run.
|
|
73
|
+
|
|
74
|
+
## Background dispatch
|
|
75
|
+
|
|
76
|
+
`background` enqueues `DispatchSubscribersJob` through Active Job, so it uses whatever
|
|
77
|
+
queue adapter your app has configured. The event is serialised to a hash and rebuilt
|
|
78
|
+
in the worker, so a subscriber receives the same `EventEngine::Event` either way.
|
|
79
|
+
|
|
80
|
+
Payloads become job arguments, so keep them serialisable — which they already are if
|
|
81
|
+
they came from a compiled catalog.
|
|
82
|
+
|
|
83
|
+
## When nothing runs
|
|
84
|
+
|
|
85
|
+
If a rule names `inline` or `background` and this gem is not installed, the runtime
|
|
86
|
+
raises rather than dropping the event:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
EventEngine::UnregisteredProcessorError: the rule for event :lead_created
|
|
90
|
+
(pack :marketing) names processor :inline, but no processor is registered
|
|
91
|
+
under that name
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If subscribers do not run for an event that *is* routed here, check that the
|
|
95
|
+
subscriber class has been loaded — `subscribes_to` registers at load time, so a class
|
|
96
|
+
Rails has not autoloaded yet has not registered.
|
|
97
|
+
|
|
98
|
+
## Development
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
bin/setup
|
|
102
|
+
bundle exec rake test
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The suite runs against `test/dummy`. If a sibling `../event_engine` checkout exists it
|
|
106
|
+
is used automatically; otherwise the GitHub source is.
|
|
107
|
+
|
|
108
|
+
## License
|
|
109
|
+
|
|
110
|
+
Available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
|
11
|
+
* It is generally better to create a new file per style scope.
|
|
12
|
+
*
|
|
13
|
+
*= require_tree .
|
|
14
|
+
*= require_self
|
|
15
|
+
*/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module EventEngine
|
|
2
|
+
module Subscribers
|
|
3
|
+
# Runs an event's subscribers in a background worker. Enqueued by
|
|
4
|
+
# {Processor} for +:background+ events, which dispatch their subscribers
|
|
5
|
+
# asynchronously without touching the outbox.
|
|
6
|
+
class DispatchSubscribersJob < ApplicationJob
|
|
7
|
+
queue_as :default
|
|
8
|
+
|
|
9
|
+
# @param event_name [String] the emitted event's name
|
|
10
|
+
# @param attrs [Hash] the event attributes used to rebuild the Event
|
|
11
|
+
# @return [void]
|
|
12
|
+
def perform(event_name, attrs)
|
|
13
|
+
event = EventEngine::Event.new(**attrs.deep_symbolize_keys)
|
|
14
|
+
Registry.subscribers_for(event_name).each { |subscriber| subscriber.new.handle(event) }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Event engine subscribers</title>
|
|
5
|
+
<%= csrf_meta_tags %>
|
|
6
|
+
<%= csp_meta_tag %>
|
|
7
|
+
|
|
8
|
+
<%= yield :head %>
|
|
9
|
+
|
|
10
|
+
<%= stylesheet_link_tag "event_engine/subscribers/application", media: "all" %>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
|
|
14
|
+
<%= yield %>
|
|
15
|
+
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module EventEngine
|
|
2
|
+
module Subscribers
|
|
3
|
+
# Base class for event subscribers. Subclasses declare the event they handle
|
|
4
|
+
# with +subscribes_to+ and implement +#handle(event)+. Declaring the
|
|
5
|
+
# subscription self-registers the subclass in the {Registry} at load time, so
|
|
6
|
+
# no explicit wiring is needed.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# class SendWelcomeEmail < EventEngine::Subscribers::Base
|
|
10
|
+
# subscribes_to :user_registered
|
|
11
|
+
#
|
|
12
|
+
# def handle(event)
|
|
13
|
+
# # ...
|
|
14
|
+
# end
|
|
15
|
+
# end
|
|
16
|
+
class Base
|
|
17
|
+
# Registers this subscriber class for an event.
|
|
18
|
+
#
|
|
19
|
+
# @param event_name [Symbol, String] the event to subscribe to
|
|
20
|
+
# @return [void]
|
|
21
|
+
def self.subscribes_to(event_name)
|
|
22
|
+
Registry.register(event_name, self)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Handles a dispatched event. Subclasses must override this.
|
|
26
|
+
#
|
|
27
|
+
# @param event [Object] the dispatched event
|
|
28
|
+
# @raise [NotImplementedError] if the subclass does not implement it
|
|
29
|
+
def handle(event)
|
|
30
|
+
raise NotImplementedError, "#{self.class} must implement #handle"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "rails"
|
|
2
|
+
|
|
3
|
+
module EventEngine
|
|
4
|
+
module Subscribers
|
|
5
|
+
class Engine < ::Rails::Engine
|
|
6
|
+
isolate_namespace EventEngine::Subscribers
|
|
7
|
+
|
|
8
|
+
initializer "event_engine.subscribers.register_processor" do
|
|
9
|
+
config.after_initialize do
|
|
10
|
+
processor = Processor.new
|
|
11
|
+
Processor::HANDLED_PROCESS_TYPES.each do |process_type|
|
|
12
|
+
EventEngine.register_processor(process_type, processor)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module EventEngine
|
|
2
|
+
module Subscribers
|
|
3
|
+
class Processor
|
|
4
|
+
HANDLED_PROCESS_TYPES = [ :inline, :background ].freeze
|
|
5
|
+
|
|
6
|
+
def call(event)
|
|
7
|
+
case event.process_type&.to_sym
|
|
8
|
+
when :inline then dispatch_synchronously(event)
|
|
9
|
+
when :background then dispatch_in_background(event)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def dispatch_synchronously(event)
|
|
16
|
+
Registry.subscribers_for(event.event_name).each { |subscriber| subscriber.new.handle(event) }
|
|
17
|
+
event
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def dispatch_in_background(event)
|
|
21
|
+
DispatchSubscribersJob.perform_later(event.event_name.to_s, event.to_h)
|
|
22
|
+
event
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## EventEngine::Subscribers
|
|
2
|
+
|
|
3
|
+
> **DO NOT** explore the event_engine-subscribers gem source code. This reference is the
|
|
4
|
+
> complete user-facing API, embedded verbatim into every event_engine-subscribers local so
|
|
5
|
+
> their guidance never drifts. Keep it the single source of truth.
|
|
6
|
+
|
|
7
|
+
TODO: One paragraph — what event_engine-subscribers is and the problem it solves.
|
|
8
|
+
|
|
9
|
+
### What it offers
|
|
10
|
+
|
|
11
|
+
TODO: The public API — the methods/classes/DSL a host actually calls, with tiny
|
|
12
|
+
examples. This is what the `info` and `operate` locals answer from.
|
|
13
|
+
|
|
14
|
+
### Install
|
|
15
|
+
|
|
16
|
+
TODO: The exact, correct steps to add event_engine-subscribers to a host and set it up —
|
|
17
|
+
this is what the `install` local follows. Be specific to how event_engine-subscribers is
|
|
18
|
+
actually installed (e.g. for a Rails engine: add the gem, `bundle install`,
|
|
19
|
+
install + run migrations, wire any concerns/initializers). Don't leave it
|
|
20
|
+
generic.
|
|
21
|
+
|
|
22
|
+
### EventEngine::Subscribers conventions
|
|
23
|
+
|
|
24
|
+
TODO: The conventions the `operate` local must enforce when doing
|
|
25
|
+
event_engine-subscribers work, so usage stays consistent across the host.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module EventEngine
|
|
4
|
+
module Subscribers
|
|
5
|
+
# Single source of truth for event_engine-subscribers's user-facing API, read by the
|
|
6
|
+
# the_local companion subagents so their guidance never drifts from the docs.
|
|
7
|
+
module Reference
|
|
8
|
+
DIR = File.expand_path("reference", __dir__)
|
|
9
|
+
|
|
10
|
+
def self.content
|
|
11
|
+
read("guide.md")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.read(name)
|
|
15
|
+
File.read(File.join(DIR, name)).chomp
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module EventEngine
|
|
2
|
+
module Subscribers
|
|
3
|
+
# In-memory registry mapping event names to their subscriber classes.
|
|
4
|
+
# Populated at load time (subscribers self-register via {Base.subscribes_to})
|
|
5
|
+
# and consulted when an event is dispatched, so the handler can invoke each
|
|
6
|
+
# subscriber's +#handle(event)+ in the process type's execution context.
|
|
7
|
+
class Registry
|
|
8
|
+
# Registers a subscriber class for an event.
|
|
9
|
+
#
|
|
10
|
+
# @param event_name [Symbol, String] the event to subscribe to
|
|
11
|
+
# @param subscriber [Class] a class responding to +#handle(event)+
|
|
12
|
+
# @return [void]
|
|
13
|
+
def self.register(event_name, subscriber)
|
|
14
|
+
registrations[event_name.to_sym] ||= []
|
|
15
|
+
registrations[event_name.to_sym] << subscriber
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns the subscriber classes registered for an event.
|
|
19
|
+
#
|
|
20
|
+
# @param event_name [Symbol, String]
|
|
21
|
+
# @return [Array<Class>]
|
|
22
|
+
def self.subscribers_for(event_name)
|
|
23
|
+
registrations[event_name&.to_sym] || []
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Removes all registrations. Intended for test isolation.
|
|
27
|
+
#
|
|
28
|
+
# @return [void]
|
|
29
|
+
def self.clear!
|
|
30
|
+
@registrations = {}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.registrations
|
|
34
|
+
@registrations ||= {}
|
|
35
|
+
end
|
|
36
|
+
private_class_method :registrations
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: event_engine-subscribers-info
|
|
3
|
+
description: Use to learn what event_engine-subscribers offers — its API and conventions.
|
|
4
|
+
tools: Read
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You explain what event_engine-subscribers does and how to use it, answering from the reference. You make no changes. TODO: tailor this body to event_engine-subscribers.
|
|
8
|
+
|
|
9
|
+
## EventEngine::Subscribers
|
|
10
|
+
|
|
11
|
+
> **DO NOT** explore the event_engine-subscribers gem source code. This reference is the
|
|
12
|
+
> complete user-facing API, embedded verbatim into every event_engine-subscribers local so
|
|
13
|
+
> their guidance never drifts. Keep it the single source of truth.
|
|
14
|
+
|
|
15
|
+
TODO: One paragraph — what event_engine-subscribers is and the problem it solves.
|
|
16
|
+
|
|
17
|
+
### What it offers
|
|
18
|
+
|
|
19
|
+
TODO: The public API — the methods/classes/DSL a host actually calls, with tiny
|
|
20
|
+
examples. This is what the `info` and `operate` locals answer from.
|
|
21
|
+
|
|
22
|
+
### Install
|
|
23
|
+
|
|
24
|
+
TODO: The exact, correct steps to add event_engine-subscribers to a host and set it up —
|
|
25
|
+
this is what the `install` local follows. Be specific to how event_engine-subscribers is
|
|
26
|
+
actually installed (e.g. for a Rails engine: add the gem, `bundle install`,
|
|
27
|
+
install + run migrations, wire any concerns/initializers). Don't leave it
|
|
28
|
+
generic.
|
|
29
|
+
|
|
30
|
+
### EventEngine::Subscribers conventions
|
|
31
|
+
|
|
32
|
+
TODO: The conventions the `operate` local must enforce when doing
|
|
33
|
+
event_engine-subscribers work, so usage stays consistent across the host.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: event_engine-subscribers-install
|
|
3
|
+
description: Use to add event_engine-subscribers to a project and set it up correctly.
|
|
4
|
+
tools: Bash, Read, Edit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You add event_engine-subscribers to the project and complete its setup, following the reference's install section exactly. TODO: tailor this body to event_engine-subscribers.
|
|
8
|
+
|
|
9
|
+
## EventEngine::Subscribers
|
|
10
|
+
|
|
11
|
+
> **DO NOT** explore the event_engine-subscribers gem source code. This reference is the
|
|
12
|
+
> complete user-facing API, embedded verbatim into every event_engine-subscribers local so
|
|
13
|
+
> their guidance never drifts. Keep it the single source of truth.
|
|
14
|
+
|
|
15
|
+
TODO: One paragraph — what event_engine-subscribers is and the problem it solves.
|
|
16
|
+
|
|
17
|
+
### What it offers
|
|
18
|
+
|
|
19
|
+
TODO: The public API — the methods/classes/DSL a host actually calls, with tiny
|
|
20
|
+
examples. This is what the `info` and `operate` locals answer from.
|
|
21
|
+
|
|
22
|
+
### Install
|
|
23
|
+
|
|
24
|
+
TODO: The exact, correct steps to add event_engine-subscribers to a host and set it up —
|
|
25
|
+
this is what the `install` local follows. Be specific to how event_engine-subscribers is
|
|
26
|
+
actually installed (e.g. for a Rails engine: add the gem, `bundle install`,
|
|
27
|
+
install + run migrations, wire any concerns/initializers). Don't leave it
|
|
28
|
+
generic.
|
|
29
|
+
|
|
30
|
+
### EventEngine::Subscribers conventions
|
|
31
|
+
|
|
32
|
+
TODO: The conventions the `operate` local must enforce when doing
|
|
33
|
+
event_engine-subscribers work, so usage stays consistent across the host.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: event_engine-subscribers-operate
|
|
3
|
+
description: Use PROACTIVELY for any event_engine-subscribers work. MUST BE USED instead of hand-rolling it. TODO: name the concrete tasks this local owns.
|
|
4
|
+
tools: Read, Write, Edit, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You do event_engine-subscribers work following the reference's conventions. TODO: tailor this body to event_engine-subscribers.
|
|
8
|
+
|
|
9
|
+
## EventEngine::Subscribers
|
|
10
|
+
|
|
11
|
+
> **DO NOT** explore the event_engine-subscribers gem source code. This reference is the
|
|
12
|
+
> complete user-facing API, embedded verbatim into every event_engine-subscribers local so
|
|
13
|
+
> their guidance never drifts. Keep it the single source of truth.
|
|
14
|
+
|
|
15
|
+
TODO: One paragraph — what event_engine-subscribers is and the problem it solves.
|
|
16
|
+
|
|
17
|
+
### What it offers
|
|
18
|
+
|
|
19
|
+
TODO: The public API — the methods/classes/DSL a host actually calls, with tiny
|
|
20
|
+
examples. This is what the `info` and `operate` locals answer from.
|
|
21
|
+
|
|
22
|
+
### Install
|
|
23
|
+
|
|
24
|
+
TODO: The exact, correct steps to add event_engine-subscribers to a host and set it up —
|
|
25
|
+
this is what the `install` local follows. Be specific to how event_engine-subscribers is
|
|
26
|
+
actually installed (e.g. for a Rails engine: add the gem, `bundle install`,
|
|
27
|
+
install + run migrations, wire any concerns/initializers). Don't leave it
|
|
28
|
+
generic.
|
|
29
|
+
|
|
30
|
+
### EventEngine::Subscribers conventions
|
|
31
|
+
|
|
32
|
+
TODO: The conventions the `operate` local must enforce when doing
|
|
33
|
+
event_engine-subscribers work, so usage stays consistent across the host.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "reference"
|
|
4
|
+
|
|
5
|
+
module EventEngine
|
|
6
|
+
module Subscribers
|
|
7
|
+
# Registers event_engine-subscribers's locals (Claude Code subagents) with the_local.
|
|
8
|
+
# These are the common command interface every provider exposes to apps:
|
|
9
|
+
# `info` (read-only, explains the gem), `install` (sets it up in a host), and
|
|
10
|
+
# `operate` (the proactive domain worker). Soft dependency: registration
|
|
11
|
+
# is a no-op when the_local is absent.
|
|
12
|
+
module Companion
|
|
13
|
+
def self.register!
|
|
14
|
+
TheLocal.register("event_engine-subscribers", scope: "in-app event subscribers for EventEngine — registering subscribers and running their handlers inline or in the background",
|
|
15
|
+
agents_dir: File.expand_path("the_local/agents", __dir__)) do |c|
|
|
16
|
+
c.agent "info",
|
|
17
|
+
description: "Use to learn what event_engine-subscribers offers — its API and conventions.",
|
|
18
|
+
tools: "Read",
|
|
19
|
+
body: "You explain what event_engine-subscribers does and how to use it, answering from the " \
|
|
20
|
+
"reference. You make no changes. TODO: tailor this body to event_engine-subscribers.",
|
|
21
|
+
knowledge: EventEngine::Subscribers::Reference.content
|
|
22
|
+
|
|
23
|
+
c.agent "install",
|
|
24
|
+
description: "Use to add event_engine-subscribers to a project and set it up correctly.",
|
|
25
|
+
tools: "Bash, Read, Edit",
|
|
26
|
+
body: "You add event_engine-subscribers to the project and complete its setup, following the " \
|
|
27
|
+
"reference's install section exactly. TODO: tailor this body to event_engine-subscribers.",
|
|
28
|
+
knowledge: EventEngine::Subscribers::Reference.content
|
|
29
|
+
|
|
30
|
+
c.agent "operate",
|
|
31
|
+
description: "Use PROACTIVELY for any event_engine-subscribers work. MUST BE USED instead of " \
|
|
32
|
+
"hand-rolling it. TODO: name the concrete tasks this local owns.",
|
|
33
|
+
tools: "Read, Write, Edit, Grep",
|
|
34
|
+
body: "You do event_engine-subscribers work following the reference's conventions. TODO: tailor " \
|
|
35
|
+
"this body to event_engine-subscribers.",
|
|
36
|
+
knowledge: EventEngine::Subscribers::Reference.content
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
begin
|
|
44
|
+
require "the_local"
|
|
45
|
+
EventEngine::Subscribers::Companion.register!
|
|
46
|
+
rescue LoadError
|
|
47
|
+
# the_local not installed — event_engine-subscribers works standalone.
|
|
48
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require "event_engine/subscribers/version"
|
|
2
|
+
require "event_engine/subscribers/engine"
|
|
3
|
+
require "event_engine/subscribers/registry"
|
|
4
|
+
require "event_engine/subscribers/base"
|
|
5
|
+
require "event_engine/subscribers/processor"
|
|
6
|
+
|
|
7
|
+
module EventEngine
|
|
8
|
+
module Subscribers
|
|
9
|
+
end
|
|
10
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: event_engine-subscribers
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- tylercschneider
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-07-29 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: railties
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 7.1.6
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '9'
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: 7.1.6
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '9'
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: activejob
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 7.1.6
|
|
40
|
+
- - "<"
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '9'
|
|
43
|
+
type: :runtime
|
|
44
|
+
prerelease: false
|
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: 7.1.6
|
|
50
|
+
- - "<"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '9'
|
|
53
|
+
- !ruby/object:Gem::Dependency
|
|
54
|
+
name: event_engine
|
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: 0.2.0
|
|
60
|
+
type: :runtime
|
|
61
|
+
prerelease: false
|
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: 0.2.0
|
|
67
|
+
description: 'The subscriber layer for EventEngine: runs your in-app subscribers for
|
|
68
|
+
events routed to it. Registers itself with the event_engine runtime as the :inline
|
|
69
|
+
and :background processors, running subscribers synchronously or in a background
|
|
70
|
+
job depending on which one an event''s rule names.'
|
|
71
|
+
email:
|
|
72
|
+
- tylercschneider@gmail.com
|
|
73
|
+
executables: []
|
|
74
|
+
extensions: []
|
|
75
|
+
extra_rdoc_files: []
|
|
76
|
+
files:
|
|
77
|
+
- MIT-LICENSE
|
|
78
|
+
- README.md
|
|
79
|
+
- Rakefile
|
|
80
|
+
- app/assets/stylesheets/event_engine/subscribers/application.css
|
|
81
|
+
- app/jobs/event_engine/subscribers/application_job.rb
|
|
82
|
+
- app/jobs/event_engine/subscribers/dispatch_subscribers_job.rb
|
|
83
|
+
- app/views/layouts/event_engine/subscribers/application.html.erb
|
|
84
|
+
- lib/event_engine/subscribers.rb
|
|
85
|
+
- lib/event_engine/subscribers/base.rb
|
|
86
|
+
- lib/event_engine/subscribers/engine.rb
|
|
87
|
+
- lib/event_engine/subscribers/processor.rb
|
|
88
|
+
- lib/event_engine/subscribers/reference.rb
|
|
89
|
+
- lib/event_engine/subscribers/reference/guide.md
|
|
90
|
+
- lib/event_engine/subscribers/registry.rb
|
|
91
|
+
- lib/event_engine/subscribers/the_local.rb
|
|
92
|
+
- lib/event_engine/subscribers/the_local/agents/event_engine-subscribers-info.md
|
|
93
|
+
- lib/event_engine/subscribers/the_local/agents/event_engine-subscribers-install.md
|
|
94
|
+
- lib/event_engine/subscribers/the_local/agents/event_engine-subscribers-operate.md
|
|
95
|
+
- lib/event_engine/subscribers/version.rb
|
|
96
|
+
- lib/tasks/event_engine/subscribers_tasks.rake
|
|
97
|
+
homepage: https://github.com/DYB-Development/event_engine-subscribers
|
|
98
|
+
licenses:
|
|
99
|
+
- MIT
|
|
100
|
+
metadata:
|
|
101
|
+
allowed_push_host: https://rubygems.org
|
|
102
|
+
homepage_uri: https://github.com/DYB-Development/event_engine-subscribers
|
|
103
|
+
source_code_uri: https://github.com/DYB-Development/event_engine-subscribers
|
|
104
|
+
changelog_uri: https://github.com/tylercschneider/event_engine-subscribers/blob/main/CHANGELOG.md
|
|
105
|
+
bug_tracker_uri: https://github.com/tylercschneider/event_engine-subscribers/issues
|
|
106
|
+
documentation_uri: https://github.com/tylercschneider/event_engine-subscribers#readme
|
|
107
|
+
post_install_message:
|
|
108
|
+
rdoc_options: []
|
|
109
|
+
require_paths:
|
|
110
|
+
- lib
|
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - ">="
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: 3.2.0
|
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
|
+
requirements:
|
|
118
|
+
- - ">="
|
|
119
|
+
- !ruby/object:Gem::Version
|
|
120
|
+
version: '0'
|
|
121
|
+
requirements: []
|
|
122
|
+
rubygems_version: 3.5.16
|
|
123
|
+
signing_key:
|
|
124
|
+
specification_version: 4
|
|
125
|
+
summary: In-app subscriber execution for EventEngine
|
|
126
|
+
test_files: []
|