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.
@@ -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