observers 0.5.2 → 0.6.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: 43b98e363f71c1af49c171092474b32876ed8960b95c5ec02a9583d8c86ed7f6
4
- data.tar.gz: 885c88e2e012bb1a57570a80e06838cab02c5ddd4f3efeddde73ababa6de2ebe
3
+ metadata.gz: c6d833421a632a5d73e0b3bcd73d227881b67cfa5384bb386632b04607e3745d
4
+ data.tar.gz: 458dbadf1111fa9cdbeef5d65cce5bcd8b6da3ea355c4178ced79e0c48824f50
5
5
  SHA512:
6
- metadata.gz: 2d5d49d769a470b89d5f07aa85bafd1a3f913666f5999de99d84d7649fc5c9fc829fcf555b2d487b47d2870139cc93ef7b0dad040d4a6b4cd987305f0c322ff0
7
- data.tar.gz: 72bc50b694eb42de5c8c48bc9775b5ae4386daf0dd74c0bbd2cc7be2540809505d6ef9c8c82ea3ef244fc0442acf5039c646606daf717a701827aeaf9084b98e
6
+ metadata.gz: 5e1b8ad7ac1007633742d060524135d9013972dd973676a6f89a4c831668f9a590f0106397c315e727758b6e8e30ce344529750fd33d84f3305f7bbb4c805556
7
+ data.tar.gz: ec92959757150e34c161acd7152bdd4e82501a4dc3f0e4b0ffd79cd321fc196c81ce3d148040bff9121ec651ed351d215f636ac2e3042768032dfe225fa9c241
data/lib/keys.rb ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'models/key'
4
+
5
+ module Observers
6
+ class Keys
7
+ class MissingKeyError < StandardError; end
8
+
9
+ class << self
10
+ def keys
11
+ @keys ||= {}
12
+ @keys
13
+ end
14
+
15
+ def fetch(key)
16
+ # TODO: Log instead per configuration, much better to fail silently sometimes!
17
+ keys[key] || raise(MissingKeyError, "Key key '#{key}' not found")
18
+ end
19
+
20
+ def [](key)
21
+ keys[key] || upsert(key:)
22
+ end
23
+
24
+ def upsert(key:)
25
+ keys[key] = Key.new if keys[key].nil?
26
+ keys[key]
27
+ end
28
+
29
+ def reset
30
+ @keys = {}
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Observers
4
- class Observable
4
+ class Key
5
5
  attr_reader :observers
6
6
 
7
7
  def initialize
@@ -9,11 +9,13 @@ module Observers
9
9
  end
10
10
 
11
11
  def observe(object:, action:)
12
+ # TODO: We can observe objects directly, no need to wrap in an observer... no need to let the object's observer override the action?
13
+ # A future reason I can think of for keeping observer wrapper is to track whether the object has implemented certain actions/methods.
12
14
  @observers << Observer.new(object:, action:)
13
15
  end
14
16
 
15
17
  # @returns: The result of the last observer with a non-nil value.
16
- def trigger(action:, event:)
18
+ def trigger(action: nil, event:)
17
19
  action = event.action if event && action.nil?
18
20
  action = :handle if action.nil?
19
21
 
@@ -22,18 +24,20 @@ module Observers
22
24
  @observers.each do |observer|
23
25
  result = observer.trigger(action:, event:)
24
26
  last_result = result unless result.nil?
27
+ yield if block_given?
25
28
  end
26
29
 
27
30
  last_result
28
31
  end
29
32
 
30
33
  # @returns: The result of the first observer with a non-nil value.
31
- def take(action:, event:)
34
+ def take(action: nil, event:)
32
35
  action = event.action if event && action.nil?
33
36
  action = :handle if action.nil?
34
37
 
35
38
  @observers.each do |observer|
36
39
  result = observer.trigger(action:, event:)
40
+ yield if block_given?
37
41
  return result unless result.nil?
38
42
  end
39
43
 
@@ -12,13 +12,15 @@ module Observers
12
12
  def trigger(action:, event:)
13
13
  action = @action if @action
14
14
  event ? @object.send(action, **{ event: }) : @object.send(action)
15
- rescue ArgumentError
15
+ rescue ArgumentError => e
16
16
  type = @object.instance_of?(Class) ? @object : @object.class
17
+ method_type = @object.instance_of?(Class) ? '.' : '#'
17
18
 
18
- raise ArgumentError, "#{type}##{action} has an 'event:' keyword argument but no event was sent" if event.nil?
19
+ raise ArgumentError, "#{type}##{action} has an 'event:' keyword argument but no event arg was sent" if event.nil?
19
20
 
20
- # TODO: An error here will bubble up to the observer that triggered this observer, overwriting this error with its error.
21
- raise ArgumentError, "#{event.class} sent to #{type}##{action} but it has no 'event:' keyword argument"
21
+ # Events trigger events, so the error bubbles up to becomes the error message for the next rescue's error message:
22
+ # "RequestEvent sent to Rain::Router#handle -> StatusEvent sent to Error404Node.render -> unknown keyword: :props"
23
+ raise ArgumentError, "#{event.class} sent to #{type}#{method_type}#{action} -> #{e.message}"
22
24
  end
23
25
  end
24
26
  end
data/lib/observers.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'observables'
3
+ require_relative 'keys'
4
4
  require_relative 'models/observer'
5
5
 
6
6
  module Observers
@@ -10,35 +10,35 @@ module Observers
10
10
  end
11
11
  end
12
12
 
13
- # Add an observer on the observable side.
13
+ # Add an observer on the key side.
14
14
  def observers(key = self)
15
15
  Struct.new(:key) do
16
16
  def push(object, action: nil)
17
- Observables[key].observe(object:, action:)
17
+ Keys[key].observe(object:, action:)
18
18
  end
19
19
  alias :<< :push
20
20
 
21
21
  def count
22
- Observables[key].observers.count
22
+ Keys[key].observers.count
23
23
  end
24
24
  end.new(key)
25
25
  end
26
26
 
27
27
  # Add an observer on the observer side.
28
28
  def observe(key, action: nil)
29
- Observables[key].observe(object: self, action:)
29
+ Keys[key].observe(object: self, action:)
30
30
  end
31
31
 
32
- def trigger(key = self, action: nil, event: nil)
33
- Observables.fetch(key).trigger(action:, event:)
32
+ def trigger(key: self, action: nil, event: nil)
33
+ Keys.fetch(key).trigger(action:, event:)
34
34
  end
35
35
 
36
- def take(key = self, action: nil, event: nil)
37
- Observables.fetch(key).take(action:, event:)
36
+ def take(key: self, action: nil, event: nil)
37
+ Keys.fetch(key).take(action:, event:)
38
38
  end
39
39
 
40
40
  # TODO: Provide a "pipe/port/take" method that uses ractors to be concurrent... if supplied with immutable Data?
41
41
  end
42
42
 
43
43
  # For quick debugging, not official API.
44
- OOO = Observers::Observables.observables unless defined?(OOO)
44
+ OKK = Observers::Keys.keys unless defined?(OKK)
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Observers
4
- VERSION = '0.5.2'
4
+ VERSION = '0.6.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: observers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi
@@ -30,9 +30,9 @@ executables: []
30
30
  extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
- - lib/models/observable.rb
33
+ - lib/keys.rb
34
+ - lib/models/key.rb
34
35
  - lib/models/observer.rb
35
- - lib/observables.rb
36
36
  - lib/observers.rb
37
37
  - lib/version.rb
38
38
  homepage: https://github.com/maedi/observers
@@ -54,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  requirements: []
57
- rubygems_version: 3.7.2
57
+ rubygems_version: 4.0.6
58
58
  specification_version: 4
59
59
  summary: Observe objects of any kind
60
60
  test_files: []
data/lib/observables.rb DELETED
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'models/observable'
4
-
5
- module Observers
6
- class Observables
7
- class MissingKeyError < StandardError; end
8
-
9
- class << self
10
- def observables
11
- @observables ||= {}
12
- @observables
13
- end
14
-
15
- def fetch(key)
16
- observables[key] || raise(MissingKeyError, "Observable key '#{key}' not found")
17
- end
18
-
19
- def [](key)
20
- observables[key] || upsert(key:)
21
- end
22
-
23
- def upsert(key:)
24
- observables[key] = Observable.new if observables[key].nil?
25
- observables[key]
26
- end
27
-
28
- def reset
29
- @observables = {}
30
- end
31
- end
32
- end
33
- end