midnight-business_logic 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 24cfcc468f4e7e48f77e50e2728017a106ea7a07703aa11d939781766eb5ad61
4
+ data.tar.gz: 36e4bcb84ec676b5cdb6ddd3523ec08d43630573bc9bf9602315c01db1694f75
5
+ SHA512:
6
+ metadata.gz: 0ab18cc817a8aaf3d1bbc3d4d1b7bf389de5bc91f1bbb33d673571c1402c7503b1b636316e8c846770f60d8b7a7ce8486d1fe9bb47683c282b7c94bb3006b026
7
+ data.tar.gz: fa3cdba82a930e1759665d7e13f287001f589fbdbcc84fed14625007fba5c289dc4270c4a56d70a620de2d7a6580d90c8796c5eb4e1e2a9c6a39632b5604dabc
@@ -0,0 +1,19 @@
1
+ require 'active_support/dependencies/autoload'
2
+ require_relative 'business_logic/version'
3
+
4
+ module Midnight
5
+ module Commons
6
+ extend ::ActiveSupport::Autoload
7
+
8
+ autoload :ConcurrentWriteError
9
+ autoload :NULL_EVENT_HANDLER, 'midnight/commons/constants'
10
+ end
11
+
12
+ module BusinessLogic
13
+ extend ::ActiveSupport::Autoload
14
+
15
+ autoload :AggregateRoot
16
+ autoload :Event
17
+ autoload :EventDispatcher
18
+ end
19
+ end
@@ -0,0 +1,46 @@
1
+ require 'active_support/concern'
2
+
3
+ module Midnight
4
+ module BusinessLogic
5
+ module AggregateRoot
6
+ class UnknownCommand < ArgumentError
7
+ end
8
+
9
+ extend ::ActiveSupport::Concern
10
+
11
+ def dispatch(_command)
12
+ raise UnknownCommand
13
+ end
14
+
15
+ def state
16
+ @state ||= {}
17
+ end
18
+
19
+ def pending_events
20
+ @pending_events ||= []
21
+ end
22
+
23
+ class_methods do
24
+ attr_accessor :_event_handlers
25
+
26
+ private
27
+
28
+ def on(event_class, &block)
29
+ self._event_handlers ||= {}
30
+ self._event_handlers[event_class] = block
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def apply(*events)
37
+ handlers = self.class._event_handlers || {}
38
+ events.each do |event|
39
+ handler = handlers[event.class]
40
+ instance_exec(event, &handler) if handler
41
+ pending_events << event
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,47 @@
1
+ require 'time'
2
+ require 'active_support/core_ext/time'
3
+
4
+ module Midnight
5
+ module BusinessLogic
6
+ class Event
7
+ class SchemaViolation < ArgumentError
8
+ end
9
+
10
+ DEFAULT_METADATA_GENERATOR = lambda do
11
+ {
12
+ occurred_at: ::Time.current.iso8601(6)
13
+ }
14
+ end
15
+
16
+ def initialize(data: {}, metadata: nil)
17
+ @data = data
18
+ @metadata = metadata || DEFAULT_METADATA_GENERATOR.call
19
+ freeze
20
+ end
21
+
22
+ attr_reader :data, :metadata
23
+
24
+ class << self
25
+ def strict(data: {}, metadata: nil)
26
+ ensure_schema(data)
27
+ new(
28
+ data: data,
29
+ metadata: metadata
30
+ )
31
+ end
32
+
33
+ private
34
+
35
+ def ensure_schema(_data)
36
+ raise NotImplementedError
37
+ # example
38
+ # @data_schema ||= ::Dry::Schema.Params do
39
+ # required(:example_field).filled(:string)
40
+ # end
41
+ # result = @data_schema.call(data)
42
+ # raise SchemaViolation unless result.success?
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,69 @@
1
+ require 'active_support/core_ext/object/blank'
2
+
3
+ module Midnight
4
+ module BusinessLogic
5
+ class EventDispatcher
6
+ class InvalidHandlerSupplied < ArgumentError
7
+ end
8
+
9
+ def initialize(handlers_map = {})
10
+ handlers_map.each do |_event_class, handler_list|
11
+ handler_list.each do |handler|
12
+ raise InvalidHandlerSupplied unless handler.respond_to?(:call)
13
+ # correct construction example:
14
+ # EventDispatcher.new(SomeEvent => [
15
+ # method(:puts)
16
+ # ])
17
+ end
18
+ end
19
+ @_handlers_map = handlers_map
20
+ freeze
21
+ end
22
+
23
+ def once(event)
24
+ handler_list = @_handlers_map[event.class]
25
+ unless handler_list.blank?
26
+ handler_list.each do |handler|
27
+ handler.call(event)
28
+ end
29
+ end
30
+ end
31
+
32
+ def batch(events)
33
+ events.each(&method(:once))
34
+ end
35
+ end
36
+
37
+ class CompositeEventDispatcher # quack like EventDispatcher
38
+ def initialize(*dispatchers)
39
+ @_dispatchers = dispatchers
40
+ freeze
41
+ end
42
+
43
+ def once(event)
44
+ @_dispatchers.each do |dispatcher|
45
+ dispatcher.once(event)
46
+ end
47
+ end
48
+
49
+ def batch(events)
50
+ events.each(&method(:once))
51
+ end
52
+ end
53
+ private_constant :CompositeEventDispatcher
54
+
55
+ class EventDispatcher
56
+ class InvalidDispatcherSupplied < ArgumentError;
57
+ end
58
+
59
+ class << self
60
+ def merge(*dispatchers)
61
+ raise InvalidDispatcherSupplied unless dispatchers.all? do |dispatcher|
62
+ dispatcher.respond_to?(:once)
63
+ end
64
+ CompositeEventDispatcher.new(*dispatchers)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,5 @@
1
+ module Midnight
2
+ module BusinessLogic
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ # just a convenient marker
2
+
3
+ module Midnight
4
+ module Commons
5
+ module ConcurrentWriteError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Midnight
2
+ module Commons
3
+ NULL_EVENT_HANDLER = lambda { |*_args| }
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: midnight-business_logic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sarun Rattanasiri
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-08-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Midnight::BusinessLogic is a toolkit for writing clean and robust business
28
+ logics agnostic to frameworks, user interfaces, and data storage. Make the business
29
+ logic fully testable and provides isolation from external side effects.
30
+ email: midnight_w@gmx.tw
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - lib/midnight/business_logic.rb
36
+ - lib/midnight/business_logic/aggregate_root.rb
37
+ - lib/midnight/business_logic/event.rb
38
+ - lib/midnight/business_logic/event_dispatcher.rb
39
+ - lib/midnight/business_logic/version.rb
40
+ - lib/midnight/commons/concurrent_write_error.rb
41
+ - lib/midnight/commons/constants.rb
42
+ homepage: https://gitlab.com/slime-systems/midnight-enterprise-toolkit/tree/master/midnight-business_logic
43
+ licenses: []
44
+ metadata: {}
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubygems_version: 3.0.3
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: A toolkit for writing enterprise business logic
64
+ test_files: []