navigable 1.1.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9a68f7f5e2ac4de908f84bdf0ead1bcddf8b07117a05cdf21ce228aad4609fb
4
- data.tar.gz: 1031b1dcc22fc53c37d9c2dde8049941e4aca4a9b975d4646242c8bc50dbc880
3
+ metadata.gz: 97471cde6b2f3d8127d70152b824662e1d62694d5c7630d05c06d5767b0fb5c7
4
+ data.tar.gz: b3bbd91964cacf1d7929419d268e6af3631a625d6ec4af7eca47741649bd4577
5
5
  SHA512:
6
- metadata.gz: 718b7b78861540d93c40df11f422a62fe11fd5c55dc1e007df7c556d4a1105201b177f7b804e775c6f5e0d4e58429b96ac35881b8016cc2aa79cc062c43f5d5e
7
- data.tar.gz: 9fe59b3b53a9dcf2653ccd34b1ae15449ebb0af35e6ae12eef9c1637f9e197f7df5a3bbe4f5f3118a185cd79eaf18871ef5d577a296d5979166b13c8d3b5c0b7
6
+ metadata.gz: 6587cf7816236fb7f68cfc7f8793ebd6c14a8684687409ef656769e93cc149e47bec147a7f2083eda4470db0c35c1bd069051a895ae5664db9cc670270f29f98
7
+ data.tar.gz: b3f81adf0992c20e928eae72e4c0911401c83ded05f2b21c92f09242948020d5f2866be96d7c622f0ded6daeb37c1cb75c3442687283513392b49368d3f19560
data/README.md CHANGED
@@ -32,22 +32,13 @@ A simple, highly-performant, Rack-based router.
32
32
  **[Navigable Server][server]** *(coming soon)*<br>
33
33
  A Rack-based server for building Ruby and Navigable web applications.
34
34
 
35
- </td>
36
- </tr>
37
- <tr height="140">
38
- <td width="130"><img alt="Telescope" src="https://raw.githubusercontent.com/first-try-software/navigable/main/assets/telescope.png"></td>
39
- <td>
40
-
41
- **Navigable API** *(coming soon)*<br>
42
- An extension of Navigable Server for building restful JSON APIs.
43
-
44
35
  </td>
45
36
  </tr>
46
37
  <tr height="140">
47
38
  <td width="130"><img alt="Map" src="https://raw.githubusercontent.com/first-try-software/navigable/main/assets/map.png"></td>
48
39
  <td>
49
40
 
50
- **Navigable GraphQL** *(coming soon)*<br>
41
+ **[Navigable GraphQL][graphql]** *(coming soon)*<br>
51
42
  An extension of Navigable Server for building GraphQL APIs.
52
43
 
53
44
  </td>
@@ -195,12 +186,6 @@ Or install it yourself as:
195
186
 
196
187
  $ gem install navigable
197
188
 
198
- ## Development
199
-
200
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
201
-
202
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
203
-
204
189
  ## Contributing
205
190
 
206
191
  Bug reports and pull requests are welcome on GitHub at https://github.com/first-try-software/navigable.
@@ -222,4 +207,5 @@ Everyone interacting in the Navigable project's codebases, issue trackers, chat
222
207
  [wiki]: https://github.com/first-try-software/navigable/wiki
223
208
  [navigable]: https://github.com/first-try-software/navigable
224
209
  [router]: https://github.com/first-try-software/navigable-router
225
- [server]: https://github.com/first-try-software/navigable-server
210
+ [server]: https://github.com/first-try-software/navigable-server
211
+ [graphql]: https://github.com/first-try-software/navigable-graphql
@@ -1,5 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
+ require 'concurrent'
3
4
  require 'manufacturable'
4
5
 
5
6
  require 'navigable/version'
@@ -4,30 +4,35 @@ require 'navigable/observable'
4
4
 
5
5
  module Navigable
6
6
  module Command
7
+ class NotFoundError < StandardError; end
8
+
7
9
  TYPE = :__command__
8
10
  EXECUTE_NOT_IMPLEMENTED_MESSAGE = 'Class must implement `execute` method.'
9
11
 
10
12
  def self.extended(base)
11
13
  base.extend(Manufacturable::Item)
14
+ base.extend(ClassMethods)
12
15
  base.include(Observable)
16
+ base.include(InstanceMethods)
17
+ end
13
18
 
14
- base.instance_eval do
15
- def corresponds_to(key)
16
- super(key, TYPE)
17
- end
19
+ module ClassMethods
20
+ def corresponds_to(key)
21
+ super(key, TYPE)
18
22
  end
23
+ end
19
24
 
20
- base.class_eval do
21
- attr_reader :params, :observers
25
+ module InstanceMethods
26
+ attr_reader :params, :observers, :resolver
22
27
 
23
- def inject(params: {}, observers: [])
24
- @params = params
25
- @observers = observers
26
- end
28
+ def inject(params: {}, observers: [], resolver: NullResolver.new)
29
+ @params = params
30
+ @observers = observers
31
+ @resolver = resolver
32
+ end
27
33
 
28
- def execute
29
- raise NotImplementedError.new(EXECUTE_NOT_IMPLEMENTED_MESSAGE)
30
- end
34
+ def execute
35
+ raise NotImplementedError.new(EXECUTE_NOT_IMPLEMENTED_MESSAGE)
31
36
  end
32
37
  end
33
38
  end
@@ -1,12 +1,12 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- require 'navigable/basic_resolver'
3
+ require 'navigable/null_resolver'
4
4
  require 'navigable/observer'
5
5
  require 'navigable/command'
6
6
 
7
7
  module Navigable
8
8
  class Dispatcher
9
- def self.dispatch(key, params: {}, resolver: BasicResolver.new)
9
+ def self.dispatch(key, params: {}, resolver: NullResolver.new)
10
10
  self.new(key, params: params, resolver: resolver).dispatch
11
11
  end
12
12
 
@@ -25,11 +25,15 @@ module Navigable
25
25
  end
26
26
 
27
27
  def observers
28
- Manufacturable.build_all(Observer::TYPE, key) { |observer| observer.inject(params: params) }.push(resolver)
28
+ Manufacturable.build_all(Observer::TYPE, key) { |observer| observer.inject(params: params) }
29
29
  end
30
30
 
31
31
  def command
32
- Manufacturable.build_one(Command::TYPE, key) { |command| command.inject(params: params, observers: observers) }
32
+ build_command.tap { |command| raise Navigable::Command::NotFoundError unless command }
33
+ end
34
+
35
+ def build_command
36
+ Manufacturable.build_one(Command::TYPE, key) { |command| command.inject(params: params, observers: observers, resolver: resolver) }
33
37
  end
34
38
  end
35
39
  end
@@ -0,0 +1,9 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Navigable
4
+ class Executor
5
+ def self.execute(&block)
6
+ ENV['CONCURRENT_OBSERVERS'] ? Concurrent.global_io_executor.post(&block) : block.call
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'navigable/resolver'
4
+
5
+ module Navigable
6
+ class NullResolver
7
+ extend Navigable::Resolver
8
+
9
+ def resolve
10
+ @result
11
+ end
12
+
13
+ ObserverMap::METHODS.values.each do |observer_method|
14
+ define_method(observer_method) do |result|
15
+ @result = result
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,39 +1,29 @@
1
1
  # frozen-string-literal: true
2
2
 
3
+ require 'navigable/observer_map'
4
+ require 'navigable/executor'
5
+
3
6
  module Navigable
4
7
  module Observable
5
8
  OBSERVERS_NOT_IMPLEMENTED_MESSAGE = 'Class must implement `observers` method.'
9
+ RESOLVER_NOT_IMPLEMENTED_MESSAGE = 'Class must implement `resolver` method.'
6
10
 
7
11
  def observers
8
12
  raise NotImplementedError.new(OBSERVERS_NOT_IMPLEMENTED_MESSAGE)
9
13
  end
10
14
 
11
- def successfully(*args)
12
- observers.each { |observer| observer.on_success(*args) }
13
- end
14
-
15
- def failed_to_validate(*args)
16
- observers.each { |observer| observer.on_failure_to_validate(*args) }
17
- end
18
-
19
- def failed_to_find(*args)
20
- observers.each { |observer| observer.on_failure_to_find(*args) }
15
+ def resolver
16
+ raise NotImplementedError.new(RESOLVER_NOT_IMPLEMENTED_MESSAGE)
21
17
  end
22
18
 
23
- def failed_to_create(*args)
24
- observers.each { |observer| observer.on_failure_to_create(*args) }
25
- end
26
-
27
- def failed_to_update(*args)
28
- observers.each { |observer| observer.on_failure_to_update(*args) }
29
- end
30
-
31
- def failed_to_delete(*args)
32
- observers.each { |observer| observer.on_failure_to_delete(*args) }
33
- end
19
+ ObserverMap::METHODS.each_pair do |observable_method, observer_method|
20
+ define_method(observable_method) do |*args|
21
+ observers.each do |observer|
22
+ Navigable::Executor.execute { observer.send(observer_method, *args) }
23
+ end
34
24
 
35
- def failed(*args)
36
- observers.each { |observer| observer.on_failure(*args) }
25
+ resolver.send(observer_method, *args)
26
+ end
37
27
  end
38
28
  end
39
29
  end
@@ -8,28 +8,30 @@ module Navigable
8
8
 
9
9
  def self.extended(base)
10
10
  base.extend(Manufacturable::Item)
11
+ base.extend(ClassMethods)
11
12
  base.include(ObserverInterface)
13
+ base.include(InstanceMethods)
14
+ end
12
15
 
13
- base.instance_eval do
14
- def observes_all_commands
15
- corresponds_to_all(TYPE)
16
- end
16
+ module ClassMethods
17
+ def observes_all_commands
18
+ corresponds_to_all(TYPE)
19
+ end
17
20
 
18
- def observes(key)
19
- corresponds_to(key, TYPE)
20
- end
21
+ def observes(key)
22
+ corresponds_to(key, TYPE)
21
23
  end
24
+ end
22
25
 
23
- base.class_eval do
24
- attr_reader :params
26
+ module InstanceMethods
27
+ attr_reader :params
25
28
 
26
- def inject(params: {})
27
- @params = params
28
- end
29
+ def inject(params: {})
30
+ @params = params
31
+ end
29
32
 
30
- def observed_command_key
31
- manufacturable_item_key
32
- end
33
+ def observed_command_key
34
+ manufacturable_item_key
33
35
  end
34
36
  end
35
37
  end
@@ -1,13 +1,11 @@
1
1
  # frozen-string-literal: true
2
2
 
3
+ require 'navigable/observer_map'
4
+
3
5
  module Navigable
4
6
  module ObserverInterface
5
- def on_success(*args, **kwargs); end
6
- def on_failure_to_validate(*args, **kwargs); end
7
- def on_failure_to_find(*args, **kwargs); end
8
- def on_failure_to_create(*args, **kwargs); end
9
- def on_failure_to_update(*args, **kwargs); end
10
- def on_failure_to_delete(*args, **kwargs); end
11
- def on_failure(*args, **kwargs); end
7
+ ObserverMap::METHODS.values.each do |observer_method|
8
+ define_method(observer_method) { |*args| }
9
+ end
12
10
  end
13
11
  end
@@ -0,0 +1,16 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Navigable
4
+ class ObserverMap
5
+ METHODS = {
6
+ successfully: :on_success,
7
+ successfully_created: :on_creation,
8
+ failed_to_validate: :on_failure_to_validate,
9
+ failed_to_find: :on_failure_to_find,
10
+ failed_to_create: :on_failure_to_create,
11
+ failed_to_update: :on_failure_to_update,
12
+ failed_to_delete: :on_failure_to_delete,
13
+ failed: :on_failure
14
+ }.freeze
15
+ end
16
+ end
@@ -4,14 +4,29 @@ require 'navigable/observer_interface'
4
4
 
5
5
  module Navigable
6
6
  module Resolver
7
- RESOLVE_NOT_IMPLEMENTED_MESSAGE = 'Class must implement `resolve` method.'
7
+ TYPE = :__resolver__
8
+ RESOLVE_NOT_IMPLEMENTED_MESSAGE = 'Resolver classes must implement a `resolve` method.'
8
9
 
9
10
  def self.extended(base)
11
+ base.extend(Manufacturable::Item)
12
+ base.extend(ClassMethods)
10
13
  base.include(ObserverInterface)
11
- base.class_eval do
12
- def resolve
13
- raise NotImplementedError.new(RESOLVE_NOT_IMPLEMENTED_MESSAGE)
14
- end
14
+ base.include(InstanceMethods)
15
+ end
16
+
17
+ module ClassMethods
18
+ def default_resolver
19
+ default_manufacturable(TYPE)
20
+ end
21
+
22
+ def resolves(key)
23
+ corresponds_to(key, TYPE)
24
+ end
25
+ end
26
+
27
+ module InstanceMethods
28
+ def resolve
29
+ raise NotImplementedError.new(RESOLVE_NOT_IMPLEMENTED_MESSAGE)
15
30
  end
16
31
  end
17
32
  end
@@ -1,5 +1,5 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Navigable
4
- VERSION = "1.1.0"
4
+ VERSION = "1.5.1"
5
5
  end
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
25
  spec.require_paths = ["lib"]
26
26
 
27
+ spec.add_dependency "concurrent-ruby", "~> 1.1.7"
27
28
  spec.add_dependency "manufacturable", "~> 1.5"
28
29
 
29
30
  spec.add_development_dependency "bundler", "~> 2.0"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: navigable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alan Ridlehoover
@@ -9,8 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-09-24 00:00:00.000000000 Z
12
+ date: 2020-12-23 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: concurrent-ruby
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 1.1.7
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 1.1.7
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: manufacturable
16
30
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +122,6 @@ extra_rdoc_files: []
108
122
  files:
109
123
  - ".gitignore"
110
124
  - ".rspec"
111
- - ".ruby-version"
112
125
  - ".travis.yml"
113
126
  - CODE_OF_CONDUCT.md
114
127
  - Gemfile
@@ -118,12 +131,14 @@ files:
118
131
  - bin/console
119
132
  - bin/setup
120
133
  - lib/navigable.rb
121
- - lib/navigable/basic_resolver.rb
122
134
  - lib/navigable/command.rb
123
135
  - lib/navigable/dispatcher.rb
136
+ - lib/navigable/executor.rb
137
+ - lib/navigable/null_resolver.rb
124
138
  - lib/navigable/observable.rb
125
139
  - lib/navigable/observer.rb
126
140
  - lib/navigable/observer_interface.rb
141
+ - lib/navigable/observer_map.rb
127
142
  - lib/navigable/resolver.rb
128
143
  - lib/navigable/version.rb
129
144
  - navigable.gemspec
@@ -1 +0,0 @@
1
- 2.7.1
@@ -1,24 +0,0 @@
1
- # frozen-string-literal: true
2
-
3
- require 'navigable/resolver'
4
-
5
- module Navigable
6
- class BasicResolver
7
- extend Navigable::Resolver
8
-
9
- def resolve
10
- @result
11
- end
12
-
13
- def on_success(result)
14
- @result = result
15
- end
16
-
17
- alias_method :on_failure_to_validate, :on_success
18
- alias_method :on_failure_to_find, :on_success
19
- alias_method :on_failure_to_create, :on_success
20
- alias_method :on_failure_to_update, :on_success
21
- alias_method :on_failure_to_delete, :on_success
22
- alias_method :on_failure, :on_success
23
- end
24
- end