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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 716f50956a3fbb10524b482e39e76df2daaad30ad67261cdb817d7376f1cb4d8
4
- data.tar.gz: deb420fac8620518e6b6ad44d57d5604c72652a9c762aee09c6c36afac104b79
3
+ metadata.gz: 2e4989c09bf4471795f9770ae4c20bd9703198f557f1df1ec75e21bbbc390e51
4
+ data.tar.gz: 52fa236f7c4dca8c782e3671e0509ebb0e7965cd94453e4a16600cd814660f20
5
5
  SHA512:
6
- metadata.gz: 3d7c5dfa75ff3ff0268aae2b98334331c5863d32b7c8e5a45b95853ade084c1dbb13e7b45421f6661cd8501411add01f8af3c6c3f9510018467592f66ad1a3ad
7
- data.tar.gz: e5856d530722f40c4f5f175b163f225ce3848cb7de923d3a4f63a1b47aa6d9d02406b9462a0bac25ba41980b55932a422bc22e0f80dfecc8a35ba024abc413f3
6
+ metadata.gz: 44864e6199ee8c8d983af7c0c6335f66dec1d55f373d30d265fee97ca88aa541c0f2fa12baa52ee9b67a6543dde8d27ddf06453498da16f6649db17e6ece9e5d
7
+ data.tar.gz: fac80ac86674542a77946912b8d58b0f0176c033958e694ab334a99f9daece138b5ccd1012cfbebbae6a0224f4ed54af7fa4f9b8e7d6d8a382624f9c5c48bf7c
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Dry::Facts
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/dry/facts`. To experiment with that code, run `bin/console` for an interactive prompt.
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/[USERNAME]/dry-facts.
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
- Type system will be used to allow generation of GraphQL from core types
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
- ## Step by step
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
- - [ ] Without input contract
54
- - [ ] Without output contract
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
- - [ ] In memory
69
+ - [x] In memory store
66
70
  - [ ] Serialization and typecasting?
67
- - [ ] Transactions, causality, correlations
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
- - [ ] Kafka
76
+ - [ ] Sequel store
77
+ - [ ] ActiveRecord store
78
+ - [ ] Redis store
79
+ - [ ] Kafka store
72
80
  - [ ] Docs from comments
73
81
  * Event
74
- - [ ] Hash
75
- - [ ] Object?
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
- - [ ] Skeleton without any functionality
82
- - [ ] Class instance
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
- - [x] From hash
103
+ - [ ] Type generation
104
+ - [ ] Mutation generation
105
+ - [ ] Query generation
106
+ - [ ] From hash
91
107
  - [ ] Naive generation
92
108
  - [ ] Customizable & helpers
93
109
  * CI
@@ -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 aggregate_data_from_events(*event_klasses)
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
- #TODO ensure same aggregate_id
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
@@ -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.new(**input)
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.new(**output)
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
@@ -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(metadata: h[:metadata], data: h[:data])
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: (generated_default_id),
73
- uuid: (generated_default_uuid),
74
+ { id: (generated_default_id),
75
+ uuid: (generated_default_uuid),
74
76
  aggregate_id: generated_default_aggregate_id,
75
- type: { name: self.class.name,
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: :aggregate_id,
13
- value: event.to_h[:data][:aggregate_id])
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
- # persist_event(event)
18
- def persist_event(event)
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.to_h
45
+ fact
46
+ .to_h
45
47
  end
46
48
 
47
49
  def deserialize_event(serialized_event)
48
- Event.from_h(serialized_event)
50
+ Event
51
+ .from_h(serialized_event)
52
+ .freeze
49
53
  end
50
54
 
51
55
  end
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module Facts
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
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.1.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-19 00:00:00.000000000 Z
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
@@ -1,9 +0,0 @@
1
- module Dry
2
- module Facts
3
- class Workflow
4
-
5
-
6
-
7
- end
8
- end
9
- end