realm-core 0.7.1 → 0.7.3

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -0
  3. data/Rakefile +19 -0
  4. metadata +25 -44
  5. data/lib/realm-core.rb +0 -6
  6. data/lib/realm.rb +0 -22
  7. data/lib/realm/action_handler.rb +0 -84
  8. data/lib/realm/action_handler/result.rb +0 -32
  9. data/lib/realm/builder.rb +0 -93
  10. data/lib/realm/command_handler.rb +0 -23
  11. data/lib/realm/config.rb +0 -57
  12. data/lib/realm/container.rb +0 -68
  13. data/lib/realm/context.rb +0 -37
  14. data/lib/realm/dependency.rb +0 -24
  15. data/lib/realm/dispatcher.rb +0 -74
  16. data/lib/realm/domain_resolver.rb +0 -59
  17. data/lib/realm/error.rb +0 -62
  18. data/lib/realm/event.rb +0 -56
  19. data/lib/realm/event_factory.rb +0 -53
  20. data/lib/realm/event_handler.rb +0 -102
  21. data/lib/realm/event_router.rb +0 -100
  22. data/lib/realm/event_router/gateway.rb +0 -50
  23. data/lib/realm/event_router/internal_loop_gateway.rb +0 -50
  24. data/lib/realm/health_status.rb +0 -46
  25. data/lib/realm/mixins/aggregate_member.rb +0 -25
  26. data/lib/realm/mixins/context_injection.rb +0 -49
  27. data/lib/realm/mixins/controller.rb +0 -53
  28. data/lib/realm/mixins/decorator.rb +0 -33
  29. data/lib/realm/mixins/dependency_injection.rb +0 -52
  30. data/lib/realm/mixins/reactive.rb +0 -32
  31. data/lib/realm/mixins/repository_helper.rb +0 -43
  32. data/lib/realm/multi_worker.rb +0 -30
  33. data/lib/realm/persistence.rb +0 -54
  34. data/lib/realm/persistence/repository_query_handler_adapter.rb +0 -24
  35. data/lib/realm/plugin.rb +0 -20
  36. data/lib/realm/query_handler.rb +0 -8
  37. data/lib/realm/runtime.rb +0 -61
  38. data/lib/realm/runtime/session.rb +0 -33
  39. data/lib/realm/types.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7384c47348b48ded26a37ce232e0ccb357a8a6e7e1f25667d614f9dc37a8af2
4
- data.tar.gz: 0b4ae6a517da7377f458111447453423652b35166fadbb60df74337727d68068
3
+ metadata.gz: 48d73715170e2bfb91f817fe7f09816980939bfd51d56e061a088908af40dd08
4
+ data.tar.gz: bde68574affd81f8eaecb821921c6dba91fe151eaa9b1703cdf31fff14e934cf
5
5
  SHA512:
6
- metadata.gz: 4aa7ec7d85ce6777b58d13f6bf3ff691e83901124951f7ebb38b60c2fbf929bf58b6daec23631f8308147be8614f7ed82edce045855620de9ba6b05abab424b0
7
- data.tar.gz: ca2605753e57f0290a2b834f455389dfcc57a0ad51515b7fdc0b75c4daf2a166d32c9039aea45ce09a9995d3807beb0ac8ae97b38c2b9682658e6d28f0237cb1
6
+ metadata.gz: ff5149ff935de4a9599679f6daf246af8c43a06b3fab9d35f941a5c7d84b05b6557b4ed13487b56f127afaabe7a4868a8900d918004214f0ab13ba359763db5f
7
+ data.tar.gz: 681487eb34d5d79f090eb505966fda04406f917051b4bd5bd8fc0aa9df7d285b5dd7e5083ffc4bcd3f71d1f93b94c21fc1c8200f6c74aca1883baff2b80ac700
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Realm
2
+
3
+ Domain layer framework following Domain-driven/CQRS design principles.
4
+
5
+ [![Build status](https://badge.buildkite.com/346cce75f6c31e0a41bb98b198e85eb6b722243624459fad9c.svg)](https://buildkite.com/reevoo/realm)
6
+
7
+ ## Service layers
8
+
9
+ We follow the standard MVC design pattern of Rails but giving the model layer more structure and guidance regarding where
10
+ to put your code. The model is split into domain layer (using our [Realm](https://github.com/reevoo/smart-mono/tree/master/gems/realm) library)
11
+ and persistence layer (using [ROM](https://rom-rb.org/) library). The individual components are explained in the following section.
12
+
13
+ ![Service layers](https://confluence-connect.gliffy.net/embed/image/d02d04b1-5e40-415f-b7ba-3a631efa9bf3.png?utm_medium=live&utm_source=custom)
14
+
15
+ Advanced components are shown in lighter color, those will be needed only later on as the service domain logic grows.
16
+
17
+ ## Model layer components
18
+
19
+ ![Service external components](https://confluence-connect.gliffy.net/embed/image/c593fcc2-304e-47c3-8e3c-b0cc09e0ed54.png?utm_medium=live&utm_source=custom)
20
+
21
+ Each service has one **domain** module which consists of multiple [**aggregate**](https://martinfowler.com/bliki/DDD_Aggregate.html) modules.
22
+ Aggregate is a cluster of domain objects that can be treated as a single unit. The only way for outer world to communicate
23
+ with aggregate is by **queries** and **commands**. Query exposes aggregate's internal state and command changes it.
24
+ The state of an aggregate is represented by tree of **entities** with one being the aggregate root and zero or more dependent
25
+ entities with *belongs_to* relation to the root entity. The state of an aggregate (entity tree) is persisted
26
+ and retrieved by **repository**. There is generally one repository per aggregate unless we split the read/write
27
+ (query/command) persistence model for that particular domain. The repository uses **relations** to access the database
28
+ tables. Each relation class represents one table.
29
+
30
+
31
+ ## Where to put my code as it grows?
32
+
33
+ TODO
34
+
35
+
36
+ ## Roadmap
37
+
38
+ - [ ] Support Ruby 3
39
+ - [ ] Make it work outside of Rails engines
40
+ - [ ] Support multiple persistence gateways in one runtime
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'Realm'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.md')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ require 'bundler/gem_tasks'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: realm-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - developers@reevoo.com
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-29 00:00:00.000000000 Z
11
+ date: 2021-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.5'
111
+ - !ruby/object:Gem::Dependency
112
+ name: zeitwerk
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.4'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.4'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: pry-byebug
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -150,52 +164,19 @@ dependencies:
150
164
  - - ">="
151
165
  - !ruby/object:Gem::Version
152
166
  version: '0'
153
- description:
154
- email:
167
+ description:
168
+ email:
155
169
  executables: []
156
170
  extensions: []
157
171
  extra_rdoc_files: []
158
172
  files:
159
- - lib/realm-core.rb
160
- - lib/realm.rb
161
- - lib/realm/action_handler.rb
162
- - lib/realm/action_handler/result.rb
163
- - lib/realm/builder.rb
164
- - lib/realm/command_handler.rb
165
- - lib/realm/config.rb
166
- - lib/realm/container.rb
167
- - lib/realm/context.rb
168
- - lib/realm/dependency.rb
169
- - lib/realm/dispatcher.rb
170
- - lib/realm/domain_resolver.rb
171
- - lib/realm/error.rb
172
- - lib/realm/event.rb
173
- - lib/realm/event_factory.rb
174
- - lib/realm/event_handler.rb
175
- - lib/realm/event_router.rb
176
- - lib/realm/event_router/gateway.rb
177
- - lib/realm/event_router/internal_loop_gateway.rb
178
- - lib/realm/health_status.rb
179
- - lib/realm/mixins/aggregate_member.rb
180
- - lib/realm/mixins/context_injection.rb
181
- - lib/realm/mixins/controller.rb
182
- - lib/realm/mixins/decorator.rb
183
- - lib/realm/mixins/dependency_injection.rb
184
- - lib/realm/mixins/reactive.rb
185
- - lib/realm/mixins/repository_helper.rb
186
- - lib/realm/multi_worker.rb
187
- - lib/realm/persistence.rb
188
- - lib/realm/persistence/repository_query_handler_adapter.rb
189
- - lib/realm/plugin.rb
190
- - lib/realm/query_handler.rb
191
- - lib/realm/runtime.rb
192
- - lib/realm/runtime/session.rb
193
- - lib/realm/types.rb
194
- homepage:
173
+ - README.md
174
+ - Rakefile
175
+ homepage:
195
176
  licenses:
196
177
  - MIT
197
178
  metadata: {}
198
- post_install_message:
179
+ post_install_message:
199
180
  rdoc_options: []
200
181
  require_paths:
201
182
  - lib
@@ -210,8 +191,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
191
  - !ruby/object:Gem::Version
211
192
  version: '0'
212
193
  requirements: []
213
- rubygems_version: 3.1.6
214
- signing_key:
194
+ rubygems_version: 3.1.4
195
+ signing_key:
215
196
  specification_version: 4
216
197
  summary: Domain layer framework following Domain-driven/CQRS design principles
217
198
  test_files: []
data/lib/realm-core.rb DELETED
@@ -1,6 +0,0 @@
1
- # rubocop:disable Naming/FileName
2
- # frozen_string_literal: true
3
-
4
- require 'realm'
5
-
6
- # rubocop:enable Naming/FileName
data/lib/realm.rb DELETED
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Dir[File.join(File.dirname(__FILE__), 'realm', '**', '*.rb')].sort.each do |f|
4
- require f
5
- end
6
-
7
- module Realm
8
- class << self
9
- # Setup realm in test/console
10
- def setup(root_module, **options)
11
- config = Realm::Config.new(root_module: root_module, **options)
12
- Realm::Builder.setup(config)
13
- end
14
-
15
- # Bind realm in service/engine
16
- def bind(root_module, **options)
17
- setup(root_module, **options).tap do |builder|
18
- root_module.define_singleton_method(:realm) { builder.runtime }
19
- end
20
- end
21
- end
22
- end
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'dry-validation'
4
- require 'active_support/core_ext/module/delegation'
5
- require 'realm/error'
6
- require 'realm/mixins/context_injection'
7
- require 'realm/mixins/repository_helper'
8
- require 'realm/mixins/aggregate_member'
9
- require_relative 'action_handler/result'
10
-
11
- module Realm
12
- class ActionHandler
13
- extend Mixins::ContextInjection::ClassMethods
14
- include Mixins::AggregateMember
15
- include Mixins::RepositoryHelper
16
-
17
- class << self
18
- attr_reader :contracts
19
-
20
- def call(action: :handle, params: {}, runtime: nil)
21
- new(runtime: runtime).(action: action, params: params)
22
- end
23
-
24
- protected
25
-
26
- def require_permission(*names)
27
- # TODO: implement
28
- end
29
-
30
- def contract(&block)
31
- @method_contract = Class.new(Dry::Validation::Contract, &block).new
32
- end
33
-
34
- def contract_schema(&block)
35
- contract { schema(&block) }
36
- end
37
-
38
- def contract_params(&block)
39
- contract { params(&block) }
40
- end
41
-
42
- def contract_json(&block)
43
- contract { json(&block) }
44
- end
45
-
46
- def method_added(method_name)
47
- super
48
- return unless defined?(@method_contract)
49
-
50
- @contracts ||= {}
51
- @contracts[method_name] = @method_contract
52
- remove_instance_variable(:@method_contract)
53
- end
54
- end
55
-
56
- def initialize(runtime: nil)
57
- @runtime = runtime
58
- end
59
-
60
- def call(action: :handle, params: {})
61
- # TODO: check permissions
62
- raise CannotHandleAction.new(self, action) unless respond_to?(action)
63
-
64
- safe_params = validate(action, params.to_h)
65
- send(action, **safe_params)
66
- end
67
-
68
- protected
69
-
70
- delegate :context, to: :@runtime
71
-
72
- private
73
-
74
- def validate(action, params)
75
- contract = self.class.contracts && self.class.contracts[action]
76
- return params unless contract
77
-
78
- result = contract.(params)
79
- raise Realm::InvalidParams, result if result.failure?
80
-
81
- result.to_h
82
- end
83
- end
84
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Realm
4
- class ActionHandler
5
- # Tuple of label and value
6
- class Result < Array
7
- def self.[](first, second = nil)
8
- return new(first, second).freeze if first.is_a?(Symbol) || first.is_a?(Realm::Event)
9
-
10
- new(second || :ok, first).freeze
11
- end
12
-
13
- def label
14
- self[0]
15
- end
16
-
17
- def event
18
- label if label.is_a?(Realm::Event)
19
- end
20
-
21
- def value
22
- self[1]
23
- end
24
-
25
- private
26
-
27
- def initialize(label, value)
28
- super([label, value])
29
- end
30
- end
31
- end
32
- end
data/lib/realm/builder.rb DELETED
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/string'
4
- require 'realm/container'
5
- require 'realm/runtime'
6
- require 'realm/domain_resolver'
7
- require 'realm/persistence'
8
- require 'realm/dispatcher'
9
- require 'realm/event_router'
10
- require 'realm/plugin'
11
-
12
- module Realm
13
- class Builder
14
- def self.setup(config)
15
- new(config).setup
16
- end
17
-
18
- def initialize(config)
19
- @config = config
20
- end
21
-
22
- def setup
23
- logger.info("Setting up #{cfg.root_module} realm")
24
- register_domain_resolver
25
- register_event_router
26
- register_runtime
27
- register_logger
28
- register_dependencies
29
- setup_plugins
30
- config_persistence
31
- self
32
- end
33
-
34
- def runtime
35
- @container.resolve(Runtime)
36
- end
37
-
38
- private
39
-
40
- def register_domain_resolver
41
- container.register_factory(DomainResolver, constantize(cfg.domain_module))
42
- end
43
-
44
- def register_event_router
45
- return if cfg.event_gateways.empty?
46
-
47
- container.register_factory(EventRouter, cfg.event_gateways, prefix: cfg.prefix)
48
- end
49
-
50
- def register_runtime
51
- container.register_factory(Runtime, container)
52
- end
53
-
54
- def register_logger
55
- container.register(:logger, logger)
56
- end
57
-
58
- def register_dependencies
59
- container.register_all(**cfg.dependencies)
60
- end
61
-
62
- def setup_plugins
63
- Plugin.descendants.each do |plugin|
64
- plugin.setup(cfg, container) if cfg.plugins.include?(plugin.plugin_name)
65
- end
66
- end
67
-
68
- def config_persistence
69
- return unless cfg.persistence_gateway.present?
70
-
71
- Persistence.setup(container, cfg.persistence_gateway[:repositories])
72
- end
73
-
74
- def constantize(*parts)
75
- return parts[0] unless parts[0].is_a?(String)
76
-
77
- parts.join('::').safe_constantize
78
- end
79
-
80
- def cfg
81
- @config
82
- end
83
-
84
- def container
85
- @container ||= Container.new
86
- end
87
-
88
- def logger
89
- @logger ||= cfg.logger || (defined?(Rails) && Rails.logger) ||
90
- Logger.new($stdout, level: ENV.fetch('LOG_LEVEL', :info).to_sym)
91
- end
92
- end
93
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/module/delegation'
4
- require 'active_support/core_ext/string'
5
- require 'realm/action_handler'
6
- require 'realm/mixins/reactive'
7
-
8
- module Realm
9
- class CommandHandler < Realm::ActionHandler
10
- include Mixins::Reactive
11
-
12
- def call(*)
13
- gateway = context[:rom]&.gateways&.dig(:default)
14
- gateway ? gateway.transaction { super } : super
15
- end
16
-
17
- protected
18
-
19
- def result(first, second = nil)
20
- Result[first, second]
21
- end
22
- end
23
- end