u-observers 0.2.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a74f927670b4695760167dbbc2c1758cedbe112233b22d938cbcd79083cd8526
4
- data.tar.gz: b268b6f4b5d9c92469c20c8ba891bc12146fa52b09e6a44ccb664c6155d9b45f
3
+ metadata.gz: 20e65a3bddc28ca3121413e665f084f096c7b266304d9c486bc2d7c9b618ab8a
4
+ data.tar.gz: 455304b5999249cd475f5df8a44e0d855333ccf208f41d9cd98c7cfe1bba3cac
5
5
  SHA512:
6
- metadata.gz: b1830ebe8c59bd1f7fe66588d2b6b5b8839b487af1fe3c75a876eecc28773996e86dbd61a65af44c28c1b29bbe1a9497a9a234801d50ec19b53878b43f85bc89
7
- data.tar.gz: 4d7d0b6289ed0045e85e4edbacd6482d11c5577932f215cab19f0885c7049a20ad2015ceffaea21e1d6a7459727dd64f370cd4555e45b97d78b2c6b1a5e31575
6
+ metadata.gz: 9fe33fb9bc6bcb060f32329e28774abb6a7b546e178e531d045043889db64c403afd00171351e733df33cc812e84763c9aaf47f89c82dc6cd37264ab8ba8fd04
7
+ data.tar.gz: af195ddbdacb7e811f8c30d45d389d4b9472df7d06966009740e8cf4400676add7d80cda18db166795fafe27ae82277ed1930a2c72053bf427f4fefe424c37bc
@@ -2,23 +2,27 @@ require 'micro/observers/version'
2
2
 
3
3
  module Micro
4
4
  module Observers
5
+ require 'micro/observers/utils'
6
+ require 'micro/observers/events_or_actions'
5
7
  require 'micro/observers/manager'
6
8
 
7
9
  module ClassMethods
8
- def call_observers(with: :call)
9
- proc do |object|
10
- Array(with)
11
- .each { |action| object.observers.call(action: action) }
12
- end
10
+ def notify_observers!(with:)
11
+ proc { |object| with.each { |evt_or_act| object.observers.notify(evt_or_act) } }
13
12
  end
14
13
 
15
- def notify_observers(with: :call)
16
- call_observers(with: with)
14
+ def notify_observers(*events)
15
+ notify_observers!(with: EventsOrActions[events])
16
+ end
17
+
18
+ def call_observers(options = Utils::EMPTY_HASH)
19
+ notify_observers!(with: EventsOrActions.fetch_actions(options))
17
20
  end
18
21
  end
19
22
 
20
23
  def self.included(base)
21
24
  base.extend(ClassMethods)
25
+ base.send(:private_class_method, :notify_observers!)
22
26
  end
23
27
 
24
28
  def observers
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Observers
5
+
6
+ module EventsOrActions
7
+ DEFAULTS = [:call]
8
+
9
+ def self.[](value)
10
+ values = Utils.compact_array(value)
11
+
12
+ values.empty? ? DEFAULTS : values
13
+ end
14
+
15
+ def self.fetch_actions(hash)
16
+ return self[hash[:actions] || hash.fetch(:action)] if hash.is_a?(Hash)
17
+
18
+ raise ArgumentError, 'expected a hash with the key :action or :actions'
19
+ end
20
+
21
+ private_constant :DEFAULTS
22
+ end
23
+
24
+ end
25
+ end
@@ -4,7 +4,9 @@ module Micro
4
4
  module Observers
5
5
 
6
6
  class Manager
7
- EMPTY_HASH = {}.freeze
7
+ EqualTo = -> (observer) do
8
+ -> item { item[0] == :observer && item[1] == observer }
9
+ end
8
10
 
9
11
  def self.for(subject)
10
12
  new(subject)
@@ -12,42 +14,79 @@ module Micro
12
14
 
13
15
  def initialize(subject, list = nil)
14
16
  @subject = subject
15
- @list = (list.kind_of?(Array) ? list : []).flatten.tap(&:compact!)
17
+
18
+ @list = Utils.compact_array(list.kind_of?(Array) ? list : [])
19
+ end
20
+
21
+ def included?(observer)
22
+ @list.any?(&EqualTo[observer])
16
23
  end
17
24
 
18
- def attach(observer, options = EMPTY_HASH)
19
- if options[:allow_duplication] || @list.none? { |obs, _data| obs == observer }
20
- @list << [observer, options[:data]]
25
+ def attach(*args)
26
+ options = args.last.is_a?(Hash) ? args.pop : Utils::EMPTY_HASH
27
+
28
+ Utils.compact_array(args).each do |observer|
29
+ if options[:allow_duplication] || !included?(observer)
30
+ @list << [:observer, observer, options[:data]]
31
+ end
21
32
  end
22
33
 
23
34
  self
24
35
  end
25
36
 
26
- def detach(observer)
27
- @list.delete_if { |obs, _data| obs == observer }
37
+ def on(options = Utils::EMPTY_HASH)
38
+ event, callable, with = options[:event], options[:call], options[:with]
39
+
40
+ return self unless event.is_a?(Symbol) && callable.respond_to?(:call)
41
+
42
+ arg = with.is_a?(Proc) ? with.call(@subject) : (arg || subject)
43
+
44
+ @list << [:callable, event, [callable, arg]]
45
+ end
46
+
47
+ def detach(*args)
48
+ Utils.compact_array(args).each do |observer|
49
+ @list.delete_if(&EqualTo[observer])
50
+ end
28
51
 
29
52
  self
30
53
  end
31
54
 
32
- def call(action: :call)
33
- @list.each do |observer, data|
34
- next unless observer.respond_to?(action)
55
+ def notify(*events)
56
+ broadcast(EventsOrActions[events])
35
57
 
36
- handler = observer.method(action)
58
+ self
59
+ end
37
60
 
38
- case handler.arity
39
- when 2 then handler.call(@subject, data)
40
- when 1 then handler.call(@subject)
41
- else raise NotImplementedError
42
- end
43
- end
61
+ def call(options = Utils::EMPTY_HASH)
62
+ broadcast(EventsOrActions.fetch_actions(options))
44
63
 
45
64
  self
46
65
  end
47
66
 
48
- alias notify call
67
+ private
68
+
69
+ def broadcast(evts_or_acts)
70
+ evts_or_acts.each do |evt_or_act|
71
+ @list.each do |strategy, observer, data|
72
+ call!(observer, strategy, data, with: evt_or_act)
73
+ end
74
+ end
75
+ end
76
+
77
+ def call!(observer, strategy, data, with:)
78
+ return data[0].call(data[1]) if strategy == :callable && observer == with
79
+
80
+ if strategy == :observer && observer.respond_to?(with)
81
+ handler = observer.method(with)
82
+
83
+ return handler.call(@subject) if handler.arity == 1
84
+
85
+ handler.call(@subject, data)
86
+ end
87
+ end
49
88
 
50
- private_constant :EMPTY_HASH
89
+ private_constant :EqualTo
51
90
  end
52
91
 
53
92
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Observers
5
+
6
+ module Utils
7
+ EMPTY_HASH = {}.freeze
8
+
9
+ def self.compact_array(value)
10
+ Array(value).flatten.tap(&:compact!)
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  module Micro
2
2
  module Observers
3
- VERSION = '0.2.0'
3
+ VERSION = '0.7.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-observers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-25 00:00:00.000000000 Z
11
+ date: 2020-09-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Simple and powerful implementation of the observer pattern.
14
14
  email:
@@ -27,7 +27,9 @@ files:
27
27
  - bin/console
28
28
  - bin/setup
29
29
  - lib/micro/observers.rb
30
+ - lib/micro/observers/events_or_actions.rb
30
31
  - lib/micro/observers/manager.rb
32
+ - lib/micro/observers/utils.rb
31
33
  - lib/micro/observers/version.rb
32
34
  - lib/u-observers.rb
33
35
  - u-observers.gemspec