midnight-business_logic 0.0.1

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 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: []