emittance 0.0.1 → 0.0.2
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 +4 -4
- data/.gitignore +3 -0
- data/.rubocop.yml +12 -0
- data/.travis.yml +3 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/LICENSE.txt +21 -0
- data/README.md +91 -3
- data/lib/emittance/action.rb +174 -181
- data/lib/emittance/broker.rb +18 -65
- data/lib/emittance/brokerage.rb +56 -0
- data/lib/emittance/brokers/synchronous.rb +15 -0
- data/lib/emittance/dispatcher.rb +115 -0
- data/lib/emittance/emitter.rb +112 -88
- data/lib/emittance/errors.rb +13 -0
- data/lib/emittance/event/event_builder.rb +143 -63
- data/lib/emittance/event.rb +66 -18
- data/lib/emittance/registration.rb +13 -9
- data/lib/emittance/version.rb +3 -1
- data/lib/emittance/watcher.rb +10 -6
- data/lib/emittance.rb +23 -8
- data/pkg/emittance-0.0.1.gem +0 -0
- metadata +11 -5
- data/.rspec_status +0 -29
- data/lib/.DS_Store +0 -0
- data/lib/emittance/.DS_Store +0 -0
@@ -1,74 +1,154 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Emittance
|
4
|
+
# @private
|
5
|
+
class Event
|
6
|
+
class EventBuilder
|
7
|
+
KLASS_NAME_SUFFIX = 'Event'
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def klass_exists_for_identifier?(identifier)
|
11
|
+
klass_name = generate_event_klass_name identifier
|
12
|
+
!!lookup_event_klass(klass_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def objects_to_klass(*objs)
|
16
|
+
klass = nil
|
17
|
+
|
18
|
+
klass ||= pass_klass_through(*objs)
|
19
|
+
klass ||= find_by_custom_identifier(*objs)
|
20
|
+
klass ||= generate_event_klass(*objs)
|
21
|
+
|
22
|
+
klass
|
23
|
+
end
|
24
|
+
|
25
|
+
def klass_to_identifier(klass)
|
26
|
+
identifier = nil
|
27
|
+
|
28
|
+
identifier ||= reverse_find_by_custom_identifier(klass)
|
29
|
+
identifier ||= convert_klass_to_identifier(klass)
|
30
|
+
|
31
|
+
identifier
|
32
|
+
end
|
33
|
+
|
34
|
+
def register_custom_identifier(klass, identifier)
|
35
|
+
CustomIdentifiers.set identifier, klass
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def pass_klass_through(*objs)
|
41
|
+
objs.length == 1 && objs[0].is_a?(Class) && objs[0] < Emittance::Event ? objs[0] : nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_by_custom_identifier(*objs)
|
45
|
+
if objs.length == 1
|
46
|
+
CustomIdentifiers.event_klass_for objs[0]
|
47
|
+
else
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def reverse_find_by_custom_identifier(klass)
|
53
|
+
CustomIdentifiers.identifier_for klass
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_event_klass_name(*objs)
|
57
|
+
klass_name_parts = objs.map { |obj| klassable_name_for obj }
|
58
|
+
dress_up_klass_name klass_name_parts
|
59
|
+
end
|
60
|
+
|
61
|
+
def generate_event_klass(*objs)
|
62
|
+
klass_name = generate_event_klass_name(*objs)
|
63
|
+
find_or_create_event_klass klass_name
|
64
|
+
end
|
65
|
+
|
66
|
+
def convert_klass_to_identifier(klass)
|
67
|
+
identifier_str = klass.name
|
68
|
+
identifier_str = undress_klass_name identifier_str
|
69
|
+
identifier_str = snake_case identifier_str
|
70
|
+
|
71
|
+
identifier_str.to_sym
|
72
|
+
end
|
73
|
+
|
74
|
+
def klassable_name_for(obj)
|
75
|
+
name_str = obj.to_s
|
76
|
+
name_str = camel_case name_str
|
77
|
+
name_str = clean_up_punctuation name_str
|
78
|
+
|
79
|
+
name_str
|
80
|
+
end
|
81
|
+
|
82
|
+
def camel_case(str)
|
83
|
+
str = str.sub(/^[a-z\d]*/) { $&.capitalize }
|
84
|
+
str.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }
|
85
|
+
end
|
86
|
+
|
87
|
+
def snake_case(str)
|
88
|
+
str.gsub(/::/, '_')
|
89
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
90
|
+
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
91
|
+
.tr("-", "_")
|
92
|
+
.downcase
|
93
|
+
end
|
94
|
+
|
95
|
+
def clean_up_punctuation(str)
|
96
|
+
str.gsub /[^A-Za-z\d]/, ''
|
97
|
+
end
|
98
|
+
|
99
|
+
def dress_up_klass_name(klass_name_parts)
|
100
|
+
"#{Array(klass_name_parts).join}#{KLASS_NAME_SUFFIX}"
|
101
|
+
end
|
102
|
+
|
103
|
+
def undress_klass_name(klass_name_str)
|
104
|
+
klass_name_str.gsub /#{KLASS_NAME_SUFFIX}$/, ''
|
105
|
+
end
|
106
|
+
|
107
|
+
def lookup_event_klass(klass_name)
|
108
|
+
if Object.const_defined? klass_name
|
109
|
+
Object.const_get klass_name
|
110
|
+
else
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def find_or_create_event_klass(klass_name)
|
116
|
+
lookup_event_klass(klass_name) || create_event_klass(klass_name)
|
117
|
+
end
|
118
|
+
|
119
|
+
def create_event_klass(klass_name)
|
120
|
+
new_klass = Class.new(Emittance::Event)
|
121
|
+
Object.const_set klass_name, new_klass
|
122
|
+
end
|
123
|
+
end
|
32
124
|
|
33
|
-
|
34
|
-
|
125
|
+
class CustomIdentifiers
|
126
|
+
@mappings = {}
|
35
127
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
128
|
+
class << self
|
129
|
+
def mapping_exists?(identifier)
|
130
|
+
!!mappings[identifier] || Emittance::Event::EventBuilder.klass_exists_for_identifier?(identifier)
|
131
|
+
end
|
40
132
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
45
|
-
.tr("-", "_")
|
46
|
-
.downcase
|
47
|
-
end
|
133
|
+
def event_klass_for(identifier)
|
134
|
+
mappings[identifier]
|
135
|
+
end
|
48
136
|
|
49
|
-
|
50
|
-
|
51
|
-
|
137
|
+
def identifier_for(event_klass)
|
138
|
+
mappings.key event_klass
|
139
|
+
end
|
52
140
|
|
53
|
-
|
54
|
-
|
55
|
-
|
141
|
+
def set(identifier, event_klass)
|
142
|
+
raise Emittance::InvalidIdentifierError, 'Event identifiers must be a Symbol.' unless identifier.is_a? Symbol
|
143
|
+
raise Emittance::IdentifierTakenError if mapping_exists? identifier
|
144
|
+
mappings[identifier] = event_klass
|
145
|
+
end
|
56
146
|
|
57
|
-
|
58
|
-
klass_name_str.gsub /#{KLASS_NAME_SUFFIX}$/, ''
|
59
|
-
end
|
147
|
+
private
|
60
148
|
|
61
|
-
|
62
|
-
|
63
|
-
create_event_klass klass_name
|
149
|
+
attr_reader :mappings
|
150
|
+
end
|
64
151
|
end
|
65
|
-
|
66
|
-
Object.const_get klass_name
|
67
|
-
end
|
68
|
-
|
69
|
-
def create_event_klass(klass_name)
|
70
|
-
new_klass = Class.new(Emittance::Event)
|
71
|
-
Object.const_set klass_name, new_klass
|
72
152
|
end
|
73
153
|
end
|
74
154
|
end
|
data/lib/emittance/event.rb
CHANGED
@@ -1,25 +1,73 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Emittance
|
4
|
+
##
|
5
|
+
# Basic usage of Emittance doesn't require that you fiddle with objects of type +Emittance::Event+. However, this
|
6
|
+
# class is open for you to inherit from in the cases where you would like to customize some aspects of the event.
|
7
|
+
#
|
8
|
+
# To define a custom event, just inherit from +Emittance::Event+:
|
9
|
+
#
|
10
|
+
# class FooEvent < Emittance::Event
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# One common use case for this is to make sure all payloads share the same format. You can do this however you'd like.
|
14
|
+
# We've provided an +InvalidPayloadError+ class for that purpose. Here's one example of how that might happen:
|
15
|
+
#
|
16
|
+
# class FooEvent < Emittance::Event
|
17
|
+
# def initialize(emitter, timestamp, payload)
|
18
|
+
# super
|
19
|
+
# validate_payload
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# private
|
23
|
+
#
|
24
|
+
# def validate_payload
|
25
|
+
# raise Emittance::InvalidPayloadError unless payload.is_a?(String)
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# == Custom Identifiers
|
30
|
+
#
|
31
|
+
# By default, the identifier for this event will be the snake_case form of the class name with +Event+ chopped off:
|
32
|
+
#
|
33
|
+
# FooEvent.identifier # => :foo
|
34
|
+
#
|
35
|
+
# You can set a custom identifier for the event class like so:
|
36
|
+
#
|
37
|
+
# FooEvent.add_identifier :bar
|
38
|
+
#
|
39
|
+
# Now, when emitters emit +:bar+, this will be the event received by watchers.
|
40
|
+
#
|
41
|
+
class Event
|
42
|
+
class << self
|
43
|
+
# @return [Symbol] the identifier that can be used by the {Emittance::Broker broker} to find event handlers
|
44
|
+
def identifier
|
45
|
+
EventBuilder.klass_to_identifier self
|
46
|
+
end
|
7
47
|
|
8
|
-
|
9
|
-
|
10
|
-
|
48
|
+
# Gives the Event object a custom identifier.
|
49
|
+
#
|
50
|
+
# @param sym [Symbol] the identifier you wish to identify this event by when emitting and watching for it
|
51
|
+
def add_identifier(sym)
|
52
|
+
EventBuilder.register_custom_identifier self, sym
|
53
|
+
end
|
54
|
+
|
55
|
+
# @private
|
56
|
+
def event_klass_for(*identifiers)
|
57
|
+
EventBuilder.objects_to_klass *identifiers
|
58
|
+
end
|
11
59
|
end
|
12
|
-
end
|
13
60
|
|
14
|
-
|
61
|
+
attr_reader :emitter, :timestamp, :payload
|
15
62
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
63
|
+
def initialize(emitter, timestamp, payload)
|
64
|
+
@emitter = emitter
|
65
|
+
@timestamp = timestamp
|
66
|
+
@payload = payload
|
67
|
+
end
|
21
68
|
|
22
|
-
|
23
|
-
|
69
|
+
def identifier
|
70
|
+
self.class.identifier
|
71
|
+
end
|
24
72
|
end
|
25
73
|
end
|
@@ -1,13 +1,17 @@
|
|
1
|
-
#
|
2
|
-
class Emittance::Registration
|
3
|
-
attr_reader :identifier
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module Emittance
|
4
|
+
# @private
|
5
|
+
class Registration
|
6
|
+
attr_reader :identifier
|
7
|
+
|
8
|
+
def initialize(identifier, &callback)
|
9
|
+
@identifier = identifier
|
10
|
+
@callback = callback
|
11
|
+
end
|
9
12
|
|
10
|
-
|
11
|
-
|
13
|
+
def call(event)
|
14
|
+
@callback.call event
|
15
|
+
end
|
12
16
|
end
|
13
17
|
end
|
data/lib/emittance/version.rb
CHANGED
data/lib/emittance/watcher.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Emittance
|
4
|
+
module Watcher
|
5
|
+
def watch(identifier, callback_method = nil, &callback)
|
6
|
+
if callback_method
|
7
|
+
Emittance::Dispatcher.register_method_call identifier, self, callback_method
|
8
|
+
else
|
9
|
+
Emittance::Dispatcher.register identifier, &callback
|
10
|
+
end
|
7
11
|
end
|
8
12
|
end
|
9
13
|
end
|
data/lib/emittance.rb
CHANGED
@@ -1,26 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'emittance/version'
|
4
|
+
require 'emittance/errors'
|
5
|
+
|
6
|
+
require 'emittance/brokerage'
|
7
|
+
require 'emittance/broker'
|
2
8
|
require 'emittance/registration'
|
3
9
|
require 'emittance/event'
|
4
10
|
require 'emittance/event/event_builder'
|
5
11
|
require 'emittance/emitter'
|
6
12
|
require 'emittance/watcher'
|
7
13
|
require 'emittance/action'
|
8
|
-
require 'emittance/
|
14
|
+
require 'emittance/dispatcher'
|
9
15
|
|
16
|
+
##
|
17
|
+
# The base namespace for this library. You can do some basic configuration stuff by calling methods on its singleton.
|
18
|
+
#
|
10
19
|
module Emittance
|
11
20
|
class << self
|
12
|
-
|
21
|
+
# Enable eventing process-wide.
|
22
|
+
def enable!
|
23
|
+
Emittance::Dispatcher.enable!
|
24
|
+
end
|
13
25
|
|
14
|
-
|
15
|
-
|
26
|
+
# Disable eventing process-wide.
|
27
|
+
def disable!
|
28
|
+
Emittance::Dispatcher.disable!
|
16
29
|
end
|
17
30
|
|
18
|
-
|
19
|
-
|
31
|
+
# @return [Boolean] true if eventing is enabled, false otherwise.
|
32
|
+
def enabled?
|
33
|
+
Emittance::Dispatcher.enabled?
|
20
34
|
end
|
21
35
|
|
22
|
-
|
23
|
-
|
36
|
+
# @private
|
37
|
+
def suppress(&blk)
|
38
|
+
Emittance::Dispatcher.suppress(&blk)
|
24
39
|
end
|
25
40
|
end
|
26
41
|
end
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emittance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tyler Guillen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -102,27 +102,33 @@ extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
104
|
- ".gitignore"
|
105
|
-
- ".
|
105
|
+
- ".rubocop.yml"
|
106
106
|
- ".ruby-version"
|
107
|
+
- ".travis.yml"
|
107
108
|
- ".yardopts"
|
109
|
+
- CODE_OF_CONDUCT.md
|
108
110
|
- Gemfile
|
109
111
|
- Gemfile.lock
|
112
|
+
- LICENSE.txt
|
110
113
|
- README.md
|
111
114
|
- Rakefile
|
112
115
|
- bin/console
|
113
116
|
- bin/setup
|
114
117
|
- emittance.gemspec
|
115
|
-
- lib/.DS_Store
|
116
118
|
- lib/emittance.rb
|
117
|
-
- lib/emittance/.DS_Store
|
118
119
|
- lib/emittance/action.rb
|
119
120
|
- lib/emittance/broker.rb
|
121
|
+
- lib/emittance/brokerage.rb
|
122
|
+
- lib/emittance/brokers/synchronous.rb
|
123
|
+
- lib/emittance/dispatcher.rb
|
120
124
|
- lib/emittance/emitter.rb
|
125
|
+
- lib/emittance/errors.rb
|
121
126
|
- lib/emittance/event.rb
|
122
127
|
- lib/emittance/event/event_builder.rb
|
123
128
|
- lib/emittance/registration.rb
|
124
129
|
- lib/emittance/version.rb
|
125
130
|
- lib/emittance/watcher.rb
|
131
|
+
- pkg/emittance-0.0.1.gem
|
126
132
|
homepage: https://github.com/aastronautss/emittance
|
127
133
|
licenses:
|
128
134
|
- MIT
|
data/.rspec_status
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
example_id | status | run_time |
|
2
|
-
----------------------------------------------------- | ------ | --------------- |
|
3
|
-
./spec/emittance/action_spec.rb[1:1:1] | passed | 0.00947 seconds |
|
4
|
-
./spec/emittance/action_spec.rb[1:1:2] | passed | 0.0006 seconds |
|
5
|
-
./spec/emittance/broker_spec.rb[1:1:1] | passed | 0.00151 seconds |
|
6
|
-
./spec/emittance/broker_spec.rb[1:2:1] | passed | 0.0004 seconds |
|
7
|
-
./spec/emittance/broker_spec.rb[1:2:2] | passed | 0.00086 seconds |
|
8
|
-
./spec/emittance/broker_spec.rb[1:3:1] | passed | 0.00018 seconds |
|
9
|
-
./spec/emittance/broker_spec.rb[1:3:2] | passed | 0.00023 seconds |
|
10
|
-
./spec/emittance/broker_spec.rb[1:4:1] | passed | 0.00016 seconds |
|
11
|
-
./spec/emittance/broker_spec.rb[1:4:2] | passed | 0.00022 seconds |
|
12
|
-
./spec/emittance/emitter_spec.rb[1:1:1] | passed | 0.00038 seconds |
|
13
|
-
./spec/emittance/emitter_spec.rb[1:1:2] | passed | 0.00016 seconds |
|
14
|
-
./spec/emittance/emitter_spec.rb[1:2:1] | passed | 0.00033 seconds |
|
15
|
-
./spec/emittance/emitter_spec.rb[1:2:2] | passed | 0.00026 seconds |
|
16
|
-
./spec/emittance/event/event_builder_spec.rb[1:1:1:1] | passed | 0.00102 seconds |
|
17
|
-
./spec/emittance/event/event_builder_spec.rb[1:1:1:2] | passed | 0.00025 seconds |
|
18
|
-
./spec/emittance/event/event_builder_spec.rb[1:1:1:3] | passed | 0.00017 seconds |
|
19
|
-
./spec/emittance/event/event_builder_spec.rb[1:1:1:4] | passed | 0.0002 seconds |
|
20
|
-
./spec/emittance/event/event_builder_spec.rb[1:1:1:5] | passed | 0.0002 seconds |
|
21
|
-
./spec/emittance/event/event_builder_spec.rb[1:1:1:6] | passed | 0.00022 seconds |
|
22
|
-
./spec/emittance/event/event_builder_spec.rb[1:1:1:7] | passed | 0.00019 seconds |
|
23
|
-
./spec/emittance/event/event_builder_spec.rb[1:1:1:8] | passed | 0.00018 seconds |
|
24
|
-
./spec/emittance/event/event_builder_spec.rb[1:1:1:9] | passed | 0.00019 seconds |
|
25
|
-
./spec/emittance/event/event_builder_spec.rb[1:2:1] | passed | 0.00018 seconds |
|
26
|
-
./spec/emittance/event/event_builder_spec.rb[1:2:2] | passed | 0.00016 seconds |
|
27
|
-
./spec/emittance/watcher_spec.rb[1:1:1] | passed | 0.0003 seconds |
|
28
|
-
./spec/emittance/watcher_spec.rb[1:1:2] | passed | 0.00027 seconds |
|
29
|
-
./spec/emittance/watcher_spec.rb[1:1:3] | passed | 0.00039 seconds |
|
data/lib/.DS_Store
DELETED
Binary file
|
data/lib/emittance/.DS_Store
DELETED
Binary file
|