emittance 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -2
- data/Gemfile.lock +1 -1
- data/README.md +3 -2
- data/Rakefile +5 -3
- data/bin/console +1 -0
- data/emittance.gemspec +15 -22
- data/lib/emittance.rb +12 -6
- data/lib/emittance/action.rb +51 -37
- data/lib/emittance/brokerage.rb +23 -7
- data/lib/emittance/dispatcher.rb +21 -72
- data/lib/emittance/emitter.rb +48 -40
- data/lib/emittance/errors.rb +5 -2
- data/lib/emittance/event.rb +82 -11
- data/lib/emittance/event_lookup.rb +315 -0
- data/lib/emittance/helpers/constant_helpers.rb +33 -0
- data/lib/emittance/helpers/string_helpers.rb +48 -0
- data/lib/emittance/registration.rb +3 -3
- data/lib/emittance/version.rb +2 -2
- data/lib/emittance/watcher.rb +12 -0
- metadata +20 -19
- data/lib/emittance/event/event_builder.rb +0 -154
- data/pkg/emittance-0.0.1.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e9a6fb1053c8170cf15f5b0591b50ee652a3e65
|
4
|
+
data.tar.gz: 99c427d6c87cddf253750f9e435454bdef626cec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54ad3b23a947f7a138c2e6182d91beb618473e0f64b7475c0236fddfdfb39aac6984e0a49534dcb630912b1d226f69c1fd2eeb2b359e41ace6d12162ad52f2c1
|
7
|
+
data.tar.gz: 842994125c20aba135f5d1daec7a7842027e47c58b2129d02cf3fb5a90f852b8a692d2dd3afaa0be338cfc5f1cfcf5e8e9e984cab9ede5009e6ee9b94c8ed9db
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- 'spec/**/*'
|
4
|
+
- 'bin/**/*'
|
5
|
+
|
1
6
|
# Metrics
|
2
7
|
|
3
8
|
Metrics/LineLength:
|
@@ -10,3 +15,8 @@ Layout/MultilineMethodCallIndentation:
|
|
10
15
|
|
11
16
|
Layout/MultilineOperationIndentation:
|
12
17
|
EnforcedStyle: indented
|
18
|
+
|
19
|
+
# Style
|
20
|
+
|
21
|
+
Style/DoubleNegation:
|
22
|
+
Enabled: false
|
data/.travis.yml
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- secure: "uBY5L4Qs7b9dEVG2XAJ2x9O+PgJTIA9Ezkiu7KrfxjNhMViSUOGmkKvVxBWKwFzChfsFT2wQK/TYcNNtpZoFCLxqyBTCFV1DLHiPQ3mAW4yHPiRbwkEX5HSjypn+4ONd+nk26hMgfrnnAoHM5m4tkAQRo1dY8ARv46iH2wctErVYzj5ACf/OUmrIoF/+QXkE98oOWLMYhtyAhmlBusdcM+czreMD2BUzFilkhVLLY41KA1f7EE0W4v8aY87SOsBR6Q6bFKXm9bW3xxR6nKHukFXgXtfkkylcGOZur8VrvTxx/NAKTOyx/mCo4h1SqwZrIJQoPh3uBwv6n41YGkIzFQoebPiUnnsVYCnlz0V2AnnCdcZ/LrpIVra+bN7bh3oMtEKmlrU8cHeRQy0HlaD9u4o1KYwlg0X8lApGpsSsc+GKAC9MzGk4P3aOWFFSxqs/oo98bhlxuCvYjEh+x/aXeOqG6a/3Vlg6p/gJPxqDlaHmF6JfYGWrCysnJQtbBAstH/HhT2XHm/96uH3OURI7o+tx/I63/Qz/YG68O0nV9leFUrcmARK8XMavn1N5BM0Uoh/XhC0JUnu3GJJ7g7kABPkck81U1qWskDMeUm8hhfJgWVSixnAxKBehX+rKrizbcj3/UyqYKy7SnNHJ6fQo34rBxDLe0O8ULbWifj5/Xg4="
|
1
4
|
language: ruby
|
2
5
|
rvm:
|
3
6
|
- 2.4.2
|
7
|
+
before_script:
|
8
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
9
|
+
- chmod +x ./cc-test-reporter
|
10
|
+
- ./cc-test-reporter before-build
|
11
|
+
after_script:
|
12
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/Gemfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
6
|
|
5
7
|
# Specify your gem's dependencies in test.gemspec
|
6
8
|
gemspec
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/aastronautss/emittance.svg?branch=master)](https://travis-ci.org/aastronautss/emittance)
|
4
4
|
[![Maintainability](https://api.codeclimate.com/v1/badges/b5900e32c5a385c96c95/maintainability)](https://codeclimate.com/github/aastronautss/emittance/maintainability)
|
5
|
+
[![Inline docs](http://inch-ci.org/github/aastronautss/emittance.svg?branch=master)](http://inch-ci.org/github/aastronautss/emittance)
|
5
6
|
|
6
7
|
Emittance is a flexible eventing library that provides a clean interface for both emitting and capturing events. It follows the following workflow:
|
7
8
|
|
@@ -50,7 +51,7 @@ Foo.emit :something_else_happened # Classes who extended Emitter can also emit e
|
|
50
51
|
As you can see, event types are identified by a symbol. More on that later. You can also pass in an optional payload, which can be any object:
|
51
52
|
|
52
53
|
```ruby
|
53
|
-
my_foo.emit :something_happened, "Here's a payload!"
|
54
|
+
my_foo.emit :something_happened, payload: "Here's a payload!"
|
54
55
|
```
|
55
56
|
|
56
57
|
The above examples are cool, but it's generally a better idea to have an object emit its own events:
|
@@ -60,7 +61,7 @@ class Foo
|
|
60
61
|
extend Emittance::Emitter
|
61
62
|
|
62
63
|
def make_something_happen
|
63
|
-
emit :something_happened, "Here's a payload!"
|
64
|
+
emit :something_happened, payload: "Here's a payload!"
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/emittance.gemspec
CHANGED
@@ -1,39 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# coding: utf-8
|
3
|
+
|
2
4
|
lib = File.expand_path('../lib', __FILE__)
|
3
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
6
|
require 'emittance/version'
|
5
7
|
|
6
8
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
|
12
|
-
spec.summary = %q{A robust and flexible eventing library for Ruby.}
|
13
|
-
spec.description = %q{A robust and flexible eventing library for Ruby.}
|
14
|
-
spec.homepage = 'https://github.com/aastronautss/emittance'
|
15
|
-
spec.license = 'MIT'
|
9
|
+
spec.name = 'emittance'
|
10
|
+
spec.version = Emittance::VERSION
|
11
|
+
spec.authors = ['Tyler Guillen']
|
12
|
+
spec.email = ['tyler@tylerguillen.com']
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
23
|
-
'public gem pushes.'
|
24
|
-
end
|
14
|
+
spec.summary = 'A robust and flexible eventing library for Ruby.'
|
15
|
+
spec.description = 'A robust and flexible eventing library for Ruby.'
|
16
|
+
spec.homepage = 'https://github.com/aastronautss/emittance'
|
17
|
+
spec.license = 'MIT'
|
25
18
|
|
26
|
-
spec.files
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
20
|
f.match(%r{^(test|spec|features)/})
|
28
21
|
end
|
29
|
-
spec.bindir
|
30
|
-
spec.executables
|
22
|
+
spec.bindir = 'exe'
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
24
|
spec.require_paths = ['lib']
|
32
25
|
|
33
26
|
spec.add_development_dependency 'bundler', '~> 1.15'
|
27
|
+
spec.add_development_dependency 'pry'
|
34
28
|
spec.add_development_dependency 'rake', '~> 10.0'
|
35
29
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
36
|
-
spec.add_development_dependency 'pry'
|
37
|
-
spec.add_development_dependency 'yard'
|
38
30
|
spec.add_development_dependency 'simplecov'
|
31
|
+
spec.add_development_dependency 'yard'
|
39
32
|
end
|
data/lib/emittance.rb
CHANGED
@@ -3,11 +3,13 @@
|
|
3
3
|
require 'emittance/version'
|
4
4
|
require 'emittance/errors'
|
5
5
|
|
6
|
+
require 'emittance/helpers/string_helpers'
|
7
|
+
require 'emittance/helpers/constant_helpers'
|
8
|
+
require 'emittance/event_lookup'
|
6
9
|
require 'emittance/brokerage'
|
7
10
|
require 'emittance/broker'
|
8
11
|
require 'emittance/registration'
|
9
12
|
require 'emittance/event'
|
10
|
-
require 'emittance/event/event_builder'
|
11
13
|
require 'emittance/emitter'
|
12
14
|
require 'emittance/watcher'
|
13
15
|
require 'emittance/action'
|
@@ -20,22 +22,26 @@ module Emittance
|
|
20
22
|
class << self
|
21
23
|
# Enable eventing process-wide.
|
22
24
|
def enable!
|
23
|
-
Emittance::
|
25
|
+
Emittance::Brokerage.enable!
|
24
26
|
end
|
25
27
|
|
26
28
|
# Disable eventing process-wide.
|
27
29
|
def disable!
|
28
|
-
Emittance::
|
30
|
+
Emittance::Brokerage.disable!
|
29
31
|
end
|
30
32
|
|
31
33
|
# @return [Boolean] true if eventing is enabled, false otherwise.
|
32
34
|
def enabled?
|
33
|
-
Emittance::
|
35
|
+
Emittance::Brokerage.enabled?
|
34
36
|
end
|
35
37
|
|
38
|
+
# Not yet implemented!
|
39
|
+
# :nocov:
|
36
40
|
# @private
|
37
|
-
def suppress(&
|
38
|
-
|
41
|
+
def suppress(&_blk)
|
42
|
+
raise NotImplementedError, "This isn't working yet!"
|
43
|
+
# Emittance::Dispatcher.suppress(&blk)
|
39
44
|
end
|
45
|
+
# :nocov:
|
40
46
|
end
|
41
47
|
end
|
data/lib/emittance/action.rb
CHANGED
@@ -122,33 +122,76 @@ module Emittance
|
|
122
122
|
|
123
123
|
# @private
|
124
124
|
class << self
|
125
|
+
include Emittance::Helpers::ConstantHelpers
|
126
|
+
|
125
127
|
def included(action_klass)
|
126
128
|
handler_klass_name = Emittance::Action.handler_klass_name(action_klass)
|
127
129
|
handler_klass = Emittance::Action.find_or_create_klass(handler_klass_name)
|
128
130
|
|
129
|
-
action_klass
|
131
|
+
setup_action_klass action_klass
|
132
|
+
setup_handler_klass handler_klass, action_klass
|
133
|
+
end
|
134
|
+
|
135
|
+
# @private
|
136
|
+
def handler_klass_name(action_klass)
|
137
|
+
"#{action_klass}Handler"
|
138
|
+
end
|
139
|
+
|
140
|
+
# @private
|
141
|
+
def emitting_event_identifier(action_klass)
|
142
|
+
Emittance::Event.event_klass_for action_klass
|
143
|
+
end
|
144
|
+
|
145
|
+
# @private
|
146
|
+
def find_or_create_klass(klass_name)
|
147
|
+
unless Object.const_defined? klass_name
|
148
|
+
set_namespaced_constant_by_name klass_name, Class.new
|
149
|
+
end
|
150
|
+
|
151
|
+
Object.const_get klass_name
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
# Class setups
|
157
|
+
|
158
|
+
def setup_action_klass(action_klass)
|
159
|
+
action_klass.class_eval(&action_klass_blk)
|
160
|
+
end
|
161
|
+
|
162
|
+
def setup_handler_klass(handler_klass, action_klass)
|
163
|
+
handler_klass.class_eval(&handler_klass_blk(action_klass))
|
164
|
+
end
|
165
|
+
|
166
|
+
# Blocks
|
167
|
+
|
168
|
+
# rubocop:disable Metrics/MethodLength
|
169
|
+
def action_klass_blk
|
170
|
+
lambda do |_klass|
|
130
171
|
extend Emittance::Emitter
|
131
172
|
|
132
173
|
class << self
|
133
|
-
|
134
|
-
def method_added(method_name)
|
174
|
+
define_method :method_added do |method_name|
|
135
175
|
emitting_method = Emittance::Action::EMITTING_METHOD
|
136
|
-
|
137
|
-
|
176
|
+
identifier = Emittance::Action.emitting_event_identifier(self)
|
177
|
+
emits_on(method_name, identifier: identifier) if method_name == emitting_method
|
178
|
+
super method_name
|
138
179
|
end
|
139
180
|
end
|
140
181
|
end
|
182
|
+
end
|
141
183
|
|
142
|
-
|
184
|
+
def handler_klass_blk(action_klass)
|
185
|
+
lambda do |_klass|
|
143
186
|
attr_reader :action
|
144
187
|
|
145
188
|
extend Emittance::Watcher
|
146
189
|
|
147
|
-
|
190
|
+
define_method :initialize do |action_obj|
|
148
191
|
@action = action_obj
|
149
192
|
end
|
150
193
|
|
151
|
-
watch Emittance::Action.
|
194
|
+
watch Emittance::Action.emitting_event_identifier(action_klass) do |event|
|
152
195
|
handler_obj = new(event.emitter)
|
153
196
|
handler_method_name = Emittance::Action::HANDLER_METHOD_NAME
|
154
197
|
|
@@ -158,35 +201,6 @@ module Emittance
|
|
158
201
|
end
|
159
202
|
end
|
160
203
|
end
|
161
|
-
|
162
|
-
# @private
|
163
|
-
def handler_klass_name(action_klass)
|
164
|
-
"#{action_klass}Handler"
|
165
|
-
end
|
166
|
-
|
167
|
-
# @private
|
168
|
-
def emitting_event_name(action_klass)
|
169
|
-
Emittance::Emitter.emitting_method_event(action_klass, Emittance::Action::EMITTING_METHOD)
|
170
|
-
end
|
171
|
-
|
172
|
-
# @private
|
173
|
-
def find_or_create_klass(klass_name)
|
174
|
-
unless Object.const_defined? klass_name
|
175
|
-
set_namespaced_constant_by_name klass_name, Class.new
|
176
|
-
end
|
177
|
-
|
178
|
-
Object.const_get klass_name
|
179
|
-
end
|
180
|
-
|
181
|
-
private
|
182
|
-
|
183
|
-
def set_namespaced_constant_by_name(const_name, obj)
|
184
|
-
names = const_name.split('::')
|
185
|
-
names.shift if names.size > 1 && names.first.empty?
|
186
|
-
|
187
|
-
namespace = names.size == 1 ? Object : Object.const_get(names[0...-1].join('::'))
|
188
|
-
namespace.const_set names.last, obj
|
189
|
-
end
|
190
204
|
end
|
191
205
|
end
|
192
206
|
end
|
data/lib/emittance/brokerage.rb
CHANGED
@@ -6,12 +6,17 @@ module Emittance
|
|
6
6
|
# contact for event propagation.
|
7
7
|
#
|
8
8
|
class Brokerage
|
9
|
+
@enabled = true
|
10
|
+
|
9
11
|
class << self
|
12
|
+
# @param event [Emittance::Event] the event object
|
13
|
+
# @param broker_id [Symbol] a symbol that can be used to identify a broker by
|
10
14
|
def send_event(event, broker_id)
|
11
15
|
broker = registry.fetch(broker_id)
|
12
16
|
broker.process_event event
|
13
17
|
end
|
14
18
|
|
19
|
+
# @param broker [Emittance::Broker] the broker you would like to register
|
15
20
|
def register_broker(broker)
|
16
21
|
registry.register broker
|
17
22
|
end
|
@@ -19,6 +24,22 @@ module Emittance
|
|
19
24
|
def registry
|
20
25
|
Emittance::Brokerage::Registry
|
21
26
|
end
|
27
|
+
|
28
|
+
def enable!
|
29
|
+
@enabled = true
|
30
|
+
end
|
31
|
+
|
32
|
+
def disable!
|
33
|
+
@enabled = false
|
34
|
+
end
|
35
|
+
|
36
|
+
def enabled?
|
37
|
+
@enabled
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_accessor :enabled
|
22
43
|
end
|
23
44
|
|
24
45
|
# @private
|
@@ -26,6 +47,8 @@ module Emittance
|
|
26
47
|
@brokers = {}
|
27
48
|
|
28
49
|
class << self
|
50
|
+
include Emittance::Helpers::StringHelpers
|
51
|
+
|
29
52
|
attr_reader :brokers
|
30
53
|
|
31
54
|
def register(broker)
|
@@ -43,13 +66,6 @@ module Emittance
|
|
43
66
|
camel_case = broker.name.split('::').last
|
44
67
|
snake_case(camel_case).to_sym
|
45
68
|
end
|
46
|
-
|
47
|
-
def snake_case(str)
|
48
|
-
str.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
49
|
-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
50
|
-
.tr('-', '_')
|
51
|
-
.downcase
|
52
|
-
end
|
53
69
|
end
|
54
70
|
end
|
55
71
|
end
|
data/lib/emittance/dispatcher.rb
CHANGED
@@ -10,13 +10,23 @@ module Emittance
|
|
10
10
|
|
11
11
|
class << self
|
12
12
|
def process_event(event)
|
13
|
-
|
13
|
+
registrations_for(event).each do |registration|
|
14
|
+
registration.call event
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def registrations_for(identifier)
|
19
|
+
event_klass = find_event_klass identifier
|
20
|
+
registrations[event_klass] ||= empty_registration
|
21
|
+
registrations[event_klass]
|
14
22
|
end
|
15
23
|
|
16
24
|
def register(identifier, &callback)
|
17
|
-
|
18
|
-
registrations[
|
19
|
-
registrations_for(
|
25
|
+
event_klass = find_event_klass identifier
|
26
|
+
registrations[event_klass] ||= empty_registration
|
27
|
+
registrations_for(event_klass) << Emittance::Registration.new(event_klass, &callback)
|
28
|
+
|
29
|
+
callback
|
20
30
|
end
|
21
31
|
|
22
32
|
def register_method_call(identifier, object, method_name)
|
@@ -24,92 +34,31 @@ module Emittance
|
|
24
34
|
end
|
25
35
|
|
26
36
|
def clear_registrations!
|
27
|
-
registrations.
|
28
|
-
clear_registrations_for!
|
37
|
+
registrations.each_key do |event_klass|
|
38
|
+
clear_registrations_for! event_klass
|
29
39
|
end
|
30
40
|
end
|
31
41
|
|
32
42
|
def clear_registrations_for!(identifier)
|
33
|
-
|
34
|
-
registrations[
|
35
|
-
end
|
36
|
-
|
37
|
-
def registrations_for(identifier)
|
38
|
-
identifier = normalize_identifier identifier
|
39
|
-
registrations[identifier] || empty_registration
|
40
|
-
end
|
41
|
-
|
42
|
-
def enable!
|
43
|
-
@enabled = true
|
44
|
-
end
|
45
|
-
|
46
|
-
def disable!
|
47
|
-
@enabled = false
|
48
|
-
end
|
49
|
-
|
50
|
-
def enabled?
|
51
|
-
@enabled
|
43
|
+
event_klass = find_event_klass identifier
|
44
|
+
registrations[event_klass].clear
|
52
45
|
end
|
53
46
|
|
54
47
|
private
|
55
48
|
|
56
|
-
attr_accessor :
|
49
|
+
attr_accessor :registrations
|
57
50
|
|
58
51
|
def empty_registration
|
59
52
|
Set.new
|
60
53
|
end
|
61
54
|
|
62
|
-
def
|
63
|
-
|
64
|
-
identifier.identifier
|
65
|
-
else
|
66
|
-
coerce_identifier_type identifier
|
67
|
-
end
|
55
|
+
def find_event_klass(event)
|
56
|
+
Emittance::EventLookup.find_event_klass(event)
|
68
57
|
end
|
69
58
|
|
70
59
|
def lambda_for_method_call(object, method_name)
|
71
60
|
->(event) { object.send method_name, event }
|
72
61
|
end
|
73
|
-
|
74
|
-
def event_klass?(identifier)
|
75
|
-
identifier.is_a?(Class) && identifier < Emittance::Event
|
76
|
-
end
|
77
|
-
|
78
|
-
def event_object?(identifier)
|
79
|
-
identifier.is_a? Emittance::Event
|
80
|
-
end
|
81
|
-
|
82
|
-
def coerce_identifier_type(identifier)
|
83
|
-
identifier.to_sym
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def initialize(suppressed = false)
|
88
|
-
@suppressed = suppressed
|
89
|
-
end
|
90
|
-
|
91
|
-
def process_event(event)
|
92
|
-
return unless enabled?
|
93
|
-
|
94
|
-
registrations_for(event).each do |registration|
|
95
|
-
registration.call event
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
private
|
100
|
-
|
101
|
-
attr_reader :suppressed
|
102
|
-
|
103
|
-
def registrations_for(event)
|
104
|
-
self.class.registrations_for event
|
105
|
-
end
|
106
|
-
|
107
|
-
def enabled?
|
108
|
-
self.class.enabled? && !suppressed?
|
109
|
-
end
|
110
|
-
|
111
|
-
def suppressed?
|
112
|
-
suppressed
|
113
62
|
end
|
114
63
|
end
|
115
64
|
end
|