emittance 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,74 +1,154 @@
1
- # @private
2
- class Emittance::Event::EventBuilder
3
- KLASS_NAME_SUFFIX = 'Event'.freeze
4
-
5
- class << self
6
- def object_to_klass(obj)
7
- return obj if pass_klass_through?(obj)
8
-
9
- klass_name = klassable_name_for obj
10
- klass_name = dress_up_klass_name klass_name
11
- find_or_create_event_klass klass_name
12
- end
13
-
14
- def klass_to_identifier(klass)
15
- identifier_str = klass.name
16
- identifier_str = undress_klass_name identifier_str
17
- identifier_str = snake_case identifier_str
18
-
19
- identifier_str.to_sym
20
- end
21
-
22
- private
23
-
24
- def pass_klass_through?(obj)
25
- obj.is_a?(Class) && obj < Emittance::Event
26
- end
27
-
28
- def klassable_name_for(obj)
29
- name_str = obj.to_s
30
- name_str = camel_case name_str
31
- name_str = clean_up_punctuation name_str
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
- name_str
34
- end
125
+ class CustomIdentifiers
126
+ @mappings = {}
35
127
 
36
- def camel_case(str)
37
- str = str.sub(/^[a-z\d]*/) { $&.capitalize }
38
- str.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }
39
- end
128
+ class << self
129
+ def mapping_exists?(identifier)
130
+ !!mappings[identifier] || Emittance::Event::EventBuilder.klass_exists_for_identifier?(identifier)
131
+ end
40
132
 
41
- def snake_case(str)
42
- str.gsub(/::/, '_')
43
- .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
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
- def clean_up_punctuation(str)
50
- str.gsub /[^A-Za-z\d]/, ''
51
- end
137
+ def identifier_for(event_klass)
138
+ mappings.key event_klass
139
+ end
52
140
 
53
- def dress_up_klass_name(klass_name)
54
- "#{klass_name}#{KLASS_NAME_SUFFIX}"
55
- end
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
- def undress_klass_name(klass_name_str)
58
- klass_name_str.gsub /#{KLASS_NAME_SUFFIX}$/, ''
59
- end
147
+ private
60
148
 
61
- def find_or_create_event_klass(klass_name)
62
- unless Object.const_defined? klass_name
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
@@ -1,25 +1,73 @@
1
- class Emittance::Event
2
- class << self
3
- # @return [Symbol] the identifier that can be used by the {Emittance::Broker broker} to find event handlers.
4
- def identifier
5
- Emittance::Event::EventBuilder.klass_to_identifier self
6
- end
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
- # @private
9
- def event_klass_for(identifier)
10
- Emittance::Event::EventBuilder.object_to_klass identifier
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
- attr_reader :emitter, :timestamp, :payload
61
+ attr_reader :emitter, :timestamp, :payload
15
62
 
16
- def initialize(emitter, timestamp, payload)
17
- @emitter = emitter
18
- @timestamp = timestamp
19
- @payload = payload
20
- end
63
+ def initialize(emitter, timestamp, payload)
64
+ @emitter = emitter
65
+ @timestamp = timestamp
66
+ @payload = payload
67
+ end
21
68
 
22
- def identifier
23
- self.class.identifier
69
+ def identifier
70
+ self.class.identifier
71
+ end
24
72
  end
25
73
  end
@@ -1,13 +1,17 @@
1
- # @private
2
- class Emittance::Registration
3
- attr_reader :identifier
1
+ # frozen_string_literal: true
4
2
 
5
- def initialize(identifier, &callback)
6
- @identifier = identifier
7
- @callback = callback
8
- end
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
- def call(event)
11
- @callback.call event
13
+ def call(event)
14
+ @callback.call event
15
+ end
12
16
  end
13
17
  end
@@ -1,3 +1,5 @@
1
+ # froze_string_literal: true
2
+
1
3
  module Emittance
2
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
3
5
  end
@@ -1,9 +1,13 @@
1
- module Emittance::Watcher
2
- def watch(identifier, callback_method = nil, &callback)
3
- if callback_method
4
- Emittance::Broker.register_method_call identifier, self, callback_method
5
- else
6
- Emittance::Broker.register identifier, &callback
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/broker'
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
- @enabled = true
21
+ # Enable eventing process-wide.
22
+ def enable!
23
+ Emittance::Dispatcher.enable!
24
+ end
13
25
 
14
- def enabled?
15
- !!@enabled
26
+ # Disable eventing process-wide.
27
+ def disable!
28
+ Emittance::Dispatcher.disable!
16
29
  end
17
30
 
18
- def enable
19
- @enabled = true
31
+ # @return [Boolean] true if eventing is enabled, false otherwise.
32
+ def enabled?
33
+ Emittance::Dispatcher.enabled?
20
34
  end
21
35
 
22
- def disable
23
- @enabled = false
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.1
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-30 00:00:00.000000000 Z
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
- - ".rspec_status"
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
Binary file