dry-facts 0.1.0 → 0.2.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 +4 -4
- data/README.md +3 -4
- data/ROADMAP.md +33 -17
- data/lib/dry/facts/aggregate.rb +18 -12
- data/lib/dry/facts/command.rb +12 -4
- data/lib/dry/facts/event.rb +6 -5
- data/lib/dry/facts/event_store.rb +10 -6
- data/lib/dry/facts/version.rb +1 -1
- metadata +2 -3
- data/lib/dry/facts/workflow.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e4989c09bf4471795f9770ae4c20bd9703198f557f1df1ec75e21bbbc390e51
|
4
|
+
data.tar.gz: 52fa236f7c4dca8c782e3671e0509ebb0e7965cd94453e4a16600cd814660f20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44864e6199ee8c8d983af7c0c6335f66dec1d55f373d30d265fee97ca88aa541c0f2fa12baa52ee9b67a6543dde8d27ddf06453498da16f6649db17e6ece9e5d
|
7
|
+
data.tar.gz: fac80ac86674542a77946912b8d58b0f0176c033958e694ab334a99f9daece138b5ccd1012cfbebbae6a0224f4ed54af7fa4f9b8e7d6d8a382624f9c5c48bf7c
|
data/README.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Dry::Facts
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
EventSourcing ruby toolkit, somewhat based on dry-rb primitives.
|
4
|
+
Opinionated. Raw.
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
@@ -32,7 +31,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
31
|
|
33
32
|
## Contributing
|
34
33
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
34
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/andriytyurnikov/dry-facts.
|
36
35
|
|
37
36
|
## License
|
38
37
|
|
data/ROADMAP.md
CHANGED
@@ -25,7 +25,10 @@ Aggregates, generate and persist events. Events persisted in EventStore.
|
|
25
25
|
|
26
26
|
## Approach
|
27
27
|
|
28
|
-
|
28
|
+
Minimal prototypes of primitives
|
29
|
+
Minimal prototype of integrated system
|
30
|
+
Minimal prototype of application based on system
|
31
|
+
Refactoring
|
29
32
|
|
30
33
|
## Challenges
|
31
34
|
|
@@ -43,16 +46,16 @@ Implements the Unit-Of-Work and Identity-Map patterns to ensure each aggregate i
|
|
43
46
|
No explicit types ?
|
44
47
|
|
45
48
|
|
46
|
-
##
|
49
|
+
## Checklist
|
47
50
|
* Command
|
48
51
|
- [x] Skeleton without any meaningful structure
|
49
52
|
- [x] With inner class input contract
|
50
53
|
- [x] With inner class output contract
|
51
54
|
- [x] With explicit method input contract
|
52
55
|
- [x] With explicit method output contract
|
53
|
-
- [
|
54
|
-
- [
|
55
|
-
- [ ] Unified result
|
56
|
+
- [x] Without input contract
|
57
|
+
- [x] Without output contract
|
58
|
+
- [ ] Unified result (Relay?)
|
56
59
|
- [ ] Multistep
|
57
60
|
- [ ] Composition
|
58
61
|
- [ ] Transactions
|
@@ -60,34 +63,47 @@ No explicit types ?
|
|
60
63
|
- [ ] Validation with contract
|
61
64
|
- [ ] Validation with multiple steps
|
62
65
|
- [ ] Validation with custom behavior in the arbitrary point of command
|
66
|
+
- [ ] Docs from comments
|
63
67
|
- [ ] Code & test generator
|
64
68
|
* EventStore
|
65
|
-
- [
|
69
|
+
- [x] In memory store
|
66
70
|
- [ ] Serialization and typecasting?
|
67
|
-
- [
|
71
|
+
- [x] Aggregates
|
72
|
+
- [ ] Causality
|
73
|
+
- [ ] Correlations
|
74
|
+
- [ ] Transactions
|
68
75
|
- [ ] Lifecycle and maintenance tasks (snapshots (rolling, deployment) and versioning)
|
69
|
-
- [ ] Sequel
|
70
|
-
- [ ] ActiveRecord
|
71
|
-
- [ ]
|
76
|
+
- [ ] Sequel store
|
77
|
+
- [ ] ActiveRecord store
|
78
|
+
- [ ] Redis store
|
79
|
+
- [ ] Kafka store
|
72
80
|
- [ ] Docs from comments
|
73
81
|
* Event
|
74
|
-
- [ ] Hash
|
75
|
-
- [
|
82
|
+
- [ ] Hash?
|
83
|
+
- [x] Object?
|
84
|
+
- [ ] Aggregate DSL
|
85
|
+
- [ ] Correlation DSL
|
86
|
+
- [ ] Causation DSL
|
87
|
+
- [ ] Module?
|
76
88
|
- [ ] With schema?
|
77
89
|
- [ ] Naming and code evolution?
|
78
90
|
- [ ] Code & test generator
|
79
91
|
- [ ] Docs from comments
|
80
92
|
* Aggregates
|
81
|
-
- [
|
82
|
-
- [
|
93
|
+
- [x] Skeleton without any functionality
|
94
|
+
- [x] Class instance
|
95
|
+
- [x] With events
|
96
|
+
- [x] Data transfer DSL
|
83
97
|
- [ ] Hash instance
|
84
|
-
- [ ] With contract
|
85
|
-
- [ ] With events
|
98
|
+
- [ ] With contract?
|
86
99
|
- [ ] Code & test generator
|
87
100
|
- [ ] Docs from comments
|
88
101
|
* GraphQL generation
|
89
102
|
- [x] Skeleton without generation
|
90
|
-
- [
|
103
|
+
- [ ] Type generation
|
104
|
+
- [ ] Mutation generation
|
105
|
+
- [ ] Query generation
|
106
|
+
- [ ] From hash
|
91
107
|
- [ ] Naive generation
|
92
108
|
- [ ] Customizable & helpers
|
93
109
|
* CI
|
data/lib/dry/facts/aggregate.rb
CHANGED
@@ -12,6 +12,17 @@ module Dry
|
|
12
12
|
attr_reader :uuid
|
13
13
|
|
14
14
|
class << self
|
15
|
+
def build_one_from_events events
|
16
|
+
self
|
17
|
+
.new(events)
|
18
|
+
end
|
19
|
+
|
20
|
+
def build_all_from_events events
|
21
|
+
events
|
22
|
+
.group_by {|e| e.aggregate_id }
|
23
|
+
.map {|_, g_events| build_one_from_events(g_events) }
|
24
|
+
end
|
25
|
+
|
15
26
|
def event_handlers
|
16
27
|
@event_handlers
|
17
28
|
end
|
@@ -25,7 +36,7 @@ module Dry
|
|
25
36
|
@event_handlers[name] = method_name
|
26
37
|
end
|
27
38
|
|
28
|
-
def
|
39
|
+
def aggregate_data_from_event_types(*event_klasses)
|
29
40
|
event_klasses.each do |klass|
|
30
41
|
define_event_handler klass.name, :_transfer_data_from_event
|
31
42
|
end
|
@@ -35,12 +46,10 @@ module Dry
|
|
35
46
|
|
36
47
|
def initialize(events)
|
37
48
|
@events = events || []
|
38
|
-
|
49
|
+
@uuid = @id = if @events.first
|
50
|
+
@events.first.aggregate_id
|
51
|
+
end
|
39
52
|
@events.each {|e| self.send :_handle_event, e}
|
40
|
-
@uuid = @id = @events.first.aggregate_id
|
41
|
-
end
|
42
|
-
|
43
|
-
def no_op
|
44
53
|
end
|
45
54
|
|
46
55
|
private
|
@@ -53,13 +62,10 @@ module Dry
|
|
53
62
|
version: '0' } }
|
54
63
|
end
|
55
64
|
|
56
|
-
def _inject_aggregate_metadata_into_event event
|
57
|
-
event.metadata[:aggregate] =
|
58
|
-
_default_aggregate_metadata
|
59
|
-
.merge(event.metadata[:aggregate] || {})
|
60
|
-
end
|
61
|
-
|
62
65
|
def _handle_event event
|
66
|
+
if self.uuid != event.metadata[:aggregate_id]
|
67
|
+
fail "This event is not mine!"
|
68
|
+
end
|
63
69
|
handler_name =
|
64
70
|
self
|
65
71
|
.class
|
data/lib/dry/facts/command.rb
CHANGED
@@ -11,7 +11,7 @@ module Dry
|
|
11
11
|
|
12
12
|
class << self
|
13
13
|
def input_contract
|
14
|
-
@input_contract
|
14
|
+
@input_contract if defined?(@input_contract)
|
15
15
|
end
|
16
16
|
|
17
17
|
def input_contract= value
|
@@ -19,7 +19,7 @@ module Dry
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def output_contract
|
22
|
-
@output_contract
|
22
|
+
@output_contract if defined?(@output_contract)
|
23
23
|
end
|
24
24
|
|
25
25
|
def output_contract= value
|
@@ -54,7 +54,7 @@ module Dry
|
|
54
54
|
self::InputContract
|
55
55
|
else
|
56
56
|
self.input_contract
|
57
|
-
end.
|
57
|
+
end.yield_self {|c| _enforce_contract_if_present(c, input) }
|
58
58
|
end
|
59
59
|
|
60
60
|
def _enforce_output_contract_on output
|
@@ -62,13 +62,21 @@ module Dry
|
|
62
62
|
self::OutputContract
|
63
63
|
else
|
64
64
|
self.output_contract
|
65
|
-
end.
|
65
|
+
end.yield_self {|c| _enforce_contract_if_present(c, output) }
|
66
66
|
end
|
67
67
|
|
68
68
|
def _execute_with input
|
69
69
|
self.new.call input
|
70
70
|
end
|
71
71
|
|
72
|
+
def _enforce_contract_if_present(contract, data)
|
73
|
+
if contract
|
74
|
+
contract.new(**data)
|
75
|
+
else
|
76
|
+
data
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
72
80
|
end
|
73
81
|
|
74
82
|
end
|
data/lib/dry/facts/event.rb
CHANGED
@@ -18,7 +18,8 @@ module Dry
|
|
18
18
|
def from_h(h)
|
19
19
|
Object
|
20
20
|
.const_get(h[:metadata][:type][:name])
|
21
|
-
.new(
|
21
|
+
.new( data: h[:data],
|
22
|
+
metadata: h[:metadata])
|
22
23
|
end
|
23
24
|
end
|
24
25
|
# object/hash
|
@@ -37,6 +38,7 @@ module Dry
|
|
37
38
|
metadata: {}
|
38
39
|
@metadata = _default_metadata_merged_with(metadata) || Hash.new
|
39
40
|
@data = {}.merge(data) || Hash.new
|
41
|
+
freeze
|
40
42
|
end
|
41
43
|
|
42
44
|
def id
|
@@ -69,11 +71,10 @@ module Dry
|
|
69
71
|
generated_default_uuid = SecureRandom.uuid
|
70
72
|
generated_default_id = generated_default_uuid
|
71
73
|
|
72
|
-
{ id:
|
73
|
-
uuid:
|
74
|
+
{ id: (generated_default_id),
|
75
|
+
uuid: (generated_default_uuid),
|
74
76
|
aggregate_id: generated_default_aggregate_id,
|
75
|
-
type:
|
76
|
-
version: 0 } }
|
77
|
+
type: { name: self.class.name } }
|
77
78
|
.merge(metadata || {})
|
78
79
|
end
|
79
80
|
|
@@ -9,15 +9,16 @@ module Dry
|
|
9
9
|
|
10
10
|
def aggregate_from_event(klass, event)
|
11
11
|
get_events_by_key(
|
12
|
-
key:
|
13
|
-
value:
|
12
|
+
key: :aggregate_id,
|
13
|
+
value: event.to_h[:data][:aggregate_id])
|
14
14
|
.yield_self {|events| klass.new(events)}
|
15
15
|
end
|
16
16
|
|
17
|
-
#
|
18
|
-
def
|
17
|
+
# persist_event_and_return(event)
|
18
|
+
def persist_event_and_return(event)
|
19
19
|
# validate & fail
|
20
20
|
@serialized_events << event.to_h
|
21
|
+
event
|
21
22
|
end
|
22
23
|
|
23
24
|
# get_event_by_id(42)
|
@@ -41,11 +42,14 @@ module Dry
|
|
41
42
|
end
|
42
43
|
|
43
44
|
def serialize_event(fact)
|
44
|
-
fact
|
45
|
+
fact
|
46
|
+
.to_h
|
45
47
|
end
|
46
48
|
|
47
49
|
def deserialize_event(serialized_event)
|
48
|
-
Event
|
50
|
+
Event
|
51
|
+
.from_h(serialized_event)
|
52
|
+
.freeze
|
49
53
|
end
|
50
54
|
|
51
55
|
end
|
data/lib/dry/facts/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-facts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andriy Tyurnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: require_all
|
@@ -174,7 +174,6 @@ files:
|
|
174
174
|
- lib/dry/facts/event.rb
|
175
175
|
- lib/dry/facts/event_store.rb
|
176
176
|
- lib/dry/facts/version.rb
|
177
|
-
- lib/dry/facts/workflow.rb
|
178
177
|
homepage: https://github.com/andriytyurnikov/dry-facts
|
179
178
|
licenses:
|
180
179
|
- MIT
|