lieutenant 0.2.0 → 0.3.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -1
- data/Gemfile +16 -0
- data/README.md +35 -21
- data/lib/lieutenant/aggregate.rb +2 -0
- data/lib/lieutenant/command_sender.rb +2 -0
- data/lib/lieutenant/config.rb +20 -6
- data/lib/lieutenant/event.rb +3 -3
- data/lib/lieutenant/event_bus/in_memory.rb +26 -0
- data/lib/lieutenant/event_bus.rb +2 -18
- data/lib/lieutenant/event_store/in_memory.rb +2 -0
- data/lib/lieutenant/event_store.rb +3 -13
- data/lib/lieutenant/projector.rb +92 -0
- data/lib/lieutenant/version.rb +1 -1
- data/lib/lieutenant.rb +1 -1
- data/lieutenant.gemspec +2 -12
- metadata +7 -133
- data/.travis.yml +0 -11
- data/lib/lieutenant/projection.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c089fabb4e4b27e50920ed0ba094a7e190da35e4
|
4
|
+
data.tar.gz: 570e7d26edeb138f2c08cc1c27ba0b30d7cca582
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d6ed77c3745f2413fa2c9cfcdcb835e4c029314a27a63596995d4f29c1de812ce3be6e03e3bf4d7b1e63107361ae7218165b1a2c56ca921eea84f61d945dc15
|
7
|
+
data.tar.gz: 5c53dc7c195b2543317ec7954ed1a17474b7f445bd5cdc917a2715dd84200371b87bfc6e1b2b87ac13a42a6730d4c2abdf116c623fa6a108cc40e4f9930aaf5f
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -5,3 +5,19 @@ source 'https://rubygems.org'
|
|
5
5
|
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
6
6
|
|
7
7
|
gemspec
|
8
|
+
|
9
|
+
group :test do
|
10
|
+
gem 'byebug'
|
11
|
+
end
|
12
|
+
|
13
|
+
group :development, :test do
|
14
|
+
gem 'bundler'
|
15
|
+
gem 'coveralls'
|
16
|
+
gem 'pry'
|
17
|
+
gem 'rake'
|
18
|
+
gem 'reek'
|
19
|
+
gem 'rspec'
|
20
|
+
gem 'rubocop'
|
21
|
+
gem 'simplecov'
|
22
|
+
gem 'yard'
|
23
|
+
end
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/lieutenant.svg)](https://badge.fury.io/rb/lieutenant)
|
6
6
|
[![Build Status](https://travis-ci.org/gabteles/lieutenant.svg?branch=master)](https://travis-ci.org/gabteles/lieutenant)
|
7
|
-
[![
|
7
|
+
[![Build Status](https://semaphoreci.com/api/v1/gabrielteles/lieutenant/branches/master/badge.svg)](https://semaphoreci.com/gabrielteles/lieutenant)
|
8
8
|
[![Maintainability](https://api.codeclimate.com/v1/badges/c96a6dd822547e657829/maintainability)](https://codeclimate.com/github/gabteles/lieutenant/maintainability)
|
9
9
|
|
10
10
|
|
@@ -48,7 +48,7 @@ By now, Lieutenant offer the components listed below. With each one, there's a d
|
|
48
48
|
- [Events](#events)
|
49
49
|
- [Event Store](#event-store)
|
50
50
|
- [Event Bus](#event-bus)
|
51
|
-
- [
|
51
|
+
- [Projectors](#projectors)
|
52
52
|
- [Configuration](#configuration)
|
53
53
|
|
54
54
|
### Commands
|
@@ -100,7 +100,7 @@ You can access the command sender throught Lieutenant's config:
|
|
100
100
|
Lieutenant.config.command_sender
|
101
101
|
```
|
102
102
|
|
103
|
-
It
|
103
|
+
It depends on all the configuration components, so be sure to config them before calling it. See [Configuration](#configuration).
|
104
104
|
|
105
105
|
Once with the Command Sender, dispatch events by using `#dispatch` (aliased as `#call`):
|
106
106
|
|
@@ -237,7 +237,7 @@ For the same reason of the command handlers, aggregates should not have side-eff
|
|
237
237
|
|
238
238
|
Events register what happened with aggregates since they were created. They have same features as `Commands`: you can use ActiveModel Validations and instantiate them using `#with` method.
|
239
239
|
|
240
|
-
Events exposes `aggregate_id` and `sequence_number`, that are used to know to which aggregate each event belongs to and it's order
|
240
|
+
Events exposes `aggregate_id` and `sequence_number`, that are used to know to which aggregate each event belongs to and it's order in the event stream. You should not worry about them, we use them internally ;)
|
241
241
|
|
242
242
|
```ruby
|
243
243
|
class MeetingScheduled
|
@@ -247,8 +247,8 @@ class MeetingScheduled
|
|
247
247
|
attr_accessor :date_start
|
248
248
|
attr_accessor :date_end
|
249
249
|
# Implicity defined:
|
250
|
-
#
|
251
|
-
#
|
250
|
+
# attr_reader :aggregate_id (Meeting room's UUID)
|
251
|
+
# attr_reader :sequence_number
|
252
252
|
end
|
253
253
|
```
|
254
254
|
|
@@ -272,17 +272,17 @@ end
|
|
272
272
|
```
|
273
273
|
|
274
274
|
|
275
|
-
###
|
275
|
+
### Projectors
|
276
276
|
|
277
|
-
The
|
277
|
+
The Projectors listens to events it is interested in and updates read models
|
278
278
|
as needed. It means that they maintain the *current* state of the data. To use
|
279
|
-
it, just include `Lieutenant::
|
279
|
+
it, just include `Lieutenant::Projector`.
|
280
280
|
|
281
281
|
```ruby
|
282
|
-
module
|
283
|
-
include Lieutenant::
|
282
|
+
module MeetingRoomProjector
|
283
|
+
include Lieutenant::Projector
|
284
284
|
|
285
|
-
on(MeetingRoomCreated) do
|
285
|
+
on(MeetingRoomCreated) do
|
286
286
|
MeetingRoomRecord.create!(
|
287
287
|
uuid: event.aggregate_id,
|
288
288
|
name: event.name,
|
@@ -290,14 +290,21 @@ module MeetingRoomProjection
|
|
290
290
|
)
|
291
291
|
end
|
292
292
|
|
293
|
-
|
293
|
+
# Also allows defining method handlers
|
294
|
+
on MeetingScheduled, handler: :meeting_scheduled
|
295
|
+
|
296
|
+
def meeting_scheduled
|
294
297
|
meeting_room = MeetingRoomRecord.find(event.aggregate_id)
|
295
|
-
meeting_room.meetings.
|
298
|
+
meeting_room.meetings.create!(
|
296
299
|
description: event.description,
|
297
300
|
date_start: event.date_start,
|
298
301
|
date_end: event.date_end
|
299
|
-
|
300
|
-
|
302
|
+
)
|
303
|
+
end
|
304
|
+
|
305
|
+
# Listening to multiple events at same time
|
306
|
+
on(MeetingRoomCreated, MeetingScheduled) do
|
307
|
+
puts "Meeting event received: #{event}"
|
301
308
|
end
|
302
309
|
end
|
303
310
|
```
|
@@ -305,16 +312,18 @@ end
|
|
305
312
|
|
306
313
|
### Configuration
|
307
314
|
|
308
|
-
Lieutenant's configuration can be modified by using an structured or block way. By default, it uses InMemory implementation of event store.
|
315
|
+
Lieutenant's configuration can be modified by using an structured or block way. By default, it uses InMemory implementation of event store and bus.
|
309
316
|
|
310
317
|
```ruby
|
311
318
|
Lieutenant.config do |configuration|
|
312
|
-
configuration.
|
319
|
+
configuration.event_bus = Lieutenant::EventBus::InMemory.new
|
320
|
+
configuration.event_store_persistence = Lieutenant::EventStore::InMemory.new
|
313
321
|
end
|
314
322
|
|
315
323
|
# OR
|
316
324
|
|
317
|
-
Lieutenant.config.
|
325
|
+
Lieutenant.config.event_bus = Lieutenant::EventBus::InMemory.new
|
326
|
+
Lieutenant.config.event_store_persistence = Lieutenant::EventStore::InMemory.new
|
318
327
|
```
|
319
328
|
|
320
329
|
You can also access configuration the same way:
|
@@ -322,6 +331,7 @@ You can also access configuration the same way:
|
|
322
331
|
```ruby
|
323
332
|
Lieutenant.config do |configuration|
|
324
333
|
configuration.event_bus # => Lieutenant::EventBus
|
334
|
+
configuration.event_store_persistence # => Lieutenant::EventStore::InMemory
|
325
335
|
configuration.event_store # => Lieutenant::EventStore::InMemory
|
326
336
|
configuration.aggregate_repository # => Lieutentant::AggregateRepository
|
327
337
|
configuration.command_sender # => Lieutenant::CommandSender
|
@@ -330,6 +340,7 @@ end
|
|
330
340
|
# OR
|
331
341
|
|
332
342
|
Lieutenant.config.event_bus # => Lieutenant::EventBus
|
343
|
+
Lieutenant.config.event_store_persistence # => Lieutenant::EventStore::InMemory
|
333
344
|
Lieutenant.config.event_store # => Lieutenant::EventStore::InMemory
|
334
345
|
Lieutenant.config.aggregate_repository # => Lieutentant::AggregateRepository
|
335
346
|
Lieutenant.config.command_sender # => Lieutenant::CommandSender
|
@@ -340,10 +351,13 @@ Lieutenant.config.command_sender # => Lieutenant::CommandSender
|
|
340
351
|
In order to give some directions to the development of this gem, the roadmap below presents in a large picture of the plans to the future (more or less ordered).
|
341
352
|
|
342
353
|
- Command retry policies
|
343
|
-
- More implementations of event store
|
344
|
-
- Sagas
|
345
354
|
- Command filters
|
346
355
|
- Better documentation
|
356
|
+
- More implementations of event bus
|
357
|
+
- More implementations of event store
|
358
|
+
- Demo application
|
359
|
+
- Migrations
|
360
|
+
- Sagas
|
347
361
|
|
348
362
|
## Development
|
349
363
|
|
data/lib/lieutenant/aggregate.rb
CHANGED
@@ -47,6 +47,7 @@ module Lieutenant
|
|
47
47
|
|
48
48
|
def apply(event_class, **params)
|
49
49
|
event = event_class.with(**params)
|
50
|
+
event.setup(@id, @version + uncommitted_events.size + 1)
|
50
51
|
internal_apply(event)
|
51
52
|
uncommitted_events << event
|
52
53
|
end
|
@@ -74,6 +75,7 @@ module Lieutenant
|
|
74
75
|
|
75
76
|
def internal_apply(event)
|
76
77
|
raise(Lieutenant::Exception, "Invalid event: #{event.inspect}") unless event.valid?
|
78
|
+
|
77
79
|
self.class.handlers_for(event.class).each { |handler| instance_exec(event, &handler) }
|
78
80
|
end
|
79
81
|
end
|
@@ -10,6 +10,7 @@ module Lieutenant
|
|
10
10
|
|
11
11
|
def register(command_class, handler)
|
12
12
|
raise(Lieutenant::Exception, "Handler for #{command_class} already registered") if handlers.key?(command_class)
|
13
|
+
|
13
14
|
handlers[command_class] = handler
|
14
15
|
end
|
15
16
|
|
@@ -17,6 +18,7 @@ module Lieutenant
|
|
17
18
|
handler = handler_for(command.class)
|
18
19
|
# TODO: Filters
|
19
20
|
raise(Lieutenant::Exception, "Invalid command: #{command.inspect}") unless command.valid?
|
21
|
+
|
20
22
|
aggregate_repository.unit_of_work.execute { |repository| handler.call(repository, command) }
|
21
23
|
# rescue Exception::ConcurrencyConflict
|
22
24
|
# TODO: implement command retry policy
|
data/lib/lieutenant/config.rb
CHANGED
@@ -3,15 +3,29 @@
|
|
3
3
|
module Lieutenant
|
4
4
|
# Manages configuration
|
5
5
|
class Config
|
6
|
+
def initialize
|
7
|
+
@event_store = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
# :reek:Attribute
|
11
|
+
attr_writer :event_bus
|
12
|
+
|
13
|
+
def event_store_persistence=(implementation)
|
14
|
+
raise "Cannot change event store's persistence after event store is initialized" if @event_store
|
15
|
+
|
16
|
+
@event_store_persistence = implementation
|
17
|
+
end
|
18
|
+
|
6
19
|
def event_bus
|
7
|
-
@event_bus ||= EventBus.new
|
20
|
+
@event_bus ||= EventBus::InMemory.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def event_store_persistence
|
24
|
+
@event_store_persistence ||= EventStore::InMemory.new
|
8
25
|
end
|
9
26
|
|
10
|
-
|
11
|
-
|
12
|
-
return @event_store_implementation = implementation if implementation
|
13
|
-
@event_store_implementation ||= EventStore::InMemory
|
14
|
-
@event_store ||= EventStore.new(@event_store_implementation, event_bus)
|
27
|
+
def event_store
|
28
|
+
@event_store ||= EventStore.new(event_store_persistence, event_bus)
|
15
29
|
end
|
16
30
|
|
17
31
|
def aggregate_repository
|
data/lib/lieutenant/event.rb
CHANGED
@@ -9,11 +9,11 @@ module Lieutenant
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
def prepare(aggregate_id, sequence_number)
|
12
|
+
def setup(aggregate_id, sequence_number)
|
15
13
|
@aggregate_id = aggregate_id
|
16
14
|
@sequence_number = sequence_number
|
17
15
|
end
|
16
|
+
|
17
|
+
attr_reader :aggregate_id, :sequence_number
|
18
18
|
end
|
19
19
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lieutenant
|
4
|
+
module EventBus
|
5
|
+
# In memory implementation of eventbus
|
6
|
+
class InMemory
|
7
|
+
def initialize
|
8
|
+
@handlers = Hash.new { [] }
|
9
|
+
end
|
10
|
+
|
11
|
+
def subscribe(*event_classes, &handler)
|
12
|
+
event_classes.each do |event_class|
|
13
|
+
handlers[event_class] = handlers[event_class].push(handler)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def publish(event)
|
18
|
+
handlers[event.class].each { |handler| handler.call(event) }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :handlers
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/lieutenant/event_bus.rb
CHANGED
@@ -2,23 +2,7 @@
|
|
2
2
|
|
3
3
|
module Lieutenant
|
4
4
|
# Publishes and receives messages from the aggregates updates
|
5
|
-
|
6
|
-
|
7
|
-
@handlers = Hash.new { [] }
|
8
|
-
end
|
9
|
-
|
10
|
-
def subscribe(*event_classes, &handler)
|
11
|
-
event_classes.each do |event_class|
|
12
|
-
handlers[event_class] = handlers[event_class].push(handler)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def publish(event)
|
17
|
-
handlers[event.class].each { |handler| handler.call(event) }
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
attr_reader :handlers
|
5
|
+
module EventBus
|
6
|
+
autoload :InMemory, 'lieutenant/event_bus/in_memory'
|
23
7
|
end
|
24
8
|
end
|
@@ -19,12 +19,14 @@ module Lieutenant
|
|
19
19
|
def event_stream_for(aggregate_id)
|
20
20
|
aggregate_stream = index[aggregate_id]
|
21
21
|
return nil unless aggregate_stream
|
22
|
+
|
22
23
|
events = aggregate_stream.lazy.map(&store.method(:[]))
|
23
24
|
Enumerator.new { |yielder| events.each(&yielder.method(:<<)) }
|
24
25
|
end
|
25
26
|
|
26
27
|
def aggregate_sequence_number(aggregate_id)
|
27
28
|
return -1 unless index.key?(aggregate_id)
|
29
|
+
|
28
30
|
store[index[aggregate_id].last].sequence_number
|
29
31
|
end
|
30
32
|
|
@@ -10,13 +10,12 @@ module Lieutenant
|
|
10
10
|
@event_bus = event_bus
|
11
11
|
end
|
12
12
|
|
13
|
+
# :reek:ControlParameter
|
13
14
|
def save_events(aggregate_id, events, expected_version)
|
14
15
|
raise(Exception::ConcurrencyConflict) if store.aggregate_sequence_number(aggregate_id) != expected_version
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
final_events.each(&event_bus.method(:publish))
|
19
|
-
end
|
17
|
+
store.persist(events)
|
18
|
+
events.each(&event_bus.method(:publish))
|
20
19
|
end
|
21
20
|
|
22
21
|
def event_stream_for(aggregate_id)
|
@@ -31,14 +30,5 @@ module Lieutenant
|
|
31
30
|
|
32
31
|
attr_reader :store
|
33
32
|
attr_reader :event_bus
|
34
|
-
|
35
|
-
PREPARE_EVENTS = lambda do |aggregate_id, events, sequence_number|
|
36
|
-
events.lazy.with_index.map do |event, idx|
|
37
|
-
event.prepare(aggregate_id, sequence_number + idx + 1)
|
38
|
-
event
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
private_constant :PREPARE_EVENTS
|
43
33
|
end
|
44
34
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lieutenant
|
4
|
+
# Projector helper. Allows clean syntax to subscribe to events:
|
5
|
+
#
|
6
|
+
# class FooProjector
|
7
|
+
# include Lieutenant::Projector
|
8
|
+
#
|
9
|
+
# on CreatedBarEvent do
|
10
|
+
# # `event` is accessible
|
11
|
+
# # ...
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Methods can also be used in order to improve legibility:
|
16
|
+
#
|
17
|
+
# class FooProjector
|
18
|
+
# include Lieutenant::Projector
|
19
|
+
#
|
20
|
+
# on DeletedBarEvent, handler: :handle_delete
|
21
|
+
#
|
22
|
+
# def handle_delete
|
23
|
+
# # `event` is accessible
|
24
|
+
# # ...
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# By default Lieutenant::Projector defines +initialize+ method, receiving the
|
29
|
+
# configuration, that it will use to find desired event bus to subscribe.
|
30
|
+
# If overriding this method is necessary, there's +initialize_projector+
|
31
|
+
# method that can be called in order to do this job, as shown:
|
32
|
+
#
|
33
|
+
# class FooProjector
|
34
|
+
# include Lieutenant::Projector
|
35
|
+
#
|
36
|
+
# def initialize(needed_parameter)
|
37
|
+
# @needed_parameter = needed_parameter
|
38
|
+
# initialize_projector # assumes that this class will always use default
|
39
|
+
# # lieutenant configuration since we're passing no
|
40
|
+
# # parameters to `initialize_projector`
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
module Projector
|
44
|
+
def self.included(base)
|
45
|
+
base.class_eval do
|
46
|
+
extend Lieutenant::Projector::ClassMethods
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Define common class methods to projectors
|
51
|
+
module ClassMethods
|
52
|
+
def on(*event_classes, handler: nil, &block)
|
53
|
+
subscriptions << { event_classes: event_classes, handler: handler, block: block }
|
54
|
+
end
|
55
|
+
|
56
|
+
def subscriptions
|
57
|
+
@subscriptions ||= []
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def handle_event(event, handler:, block:)
|
64
|
+
@event = event
|
65
|
+
effect = handler ? method(handler) : block
|
66
|
+
instance_exec(&effect)
|
67
|
+
end
|
68
|
+
|
69
|
+
def initialize_projector(config = Lieutenant.config)
|
70
|
+
@projector_config = config
|
71
|
+
subscribe_to_events
|
72
|
+
end
|
73
|
+
|
74
|
+
alias initialize initialize_projector unless method_defined? :initialize
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
attr_reader :event, :projector_config
|
79
|
+
|
80
|
+
def subscribe_to_events
|
81
|
+
self.class.subscriptions.each do |event_classes:, **kwargs|
|
82
|
+
subscribe_to_event(event_classes, kwargs)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def subscribe_to_event(event_classes, kwargs)
|
87
|
+
projector_config.event_bus.subscribe(*event_classes) do |event|
|
88
|
+
clone.handle_event(event, kwargs)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/lieutenant/version.rb
CHANGED
data/lib/lieutenant.rb
CHANGED
@@ -16,7 +16,7 @@ module Lieutenant
|
|
16
16
|
autoload :EventStore, 'lieutenant/event_store'
|
17
17
|
autoload :Exception, 'lieutenant/exception'
|
18
18
|
autoload :Message, 'lieutenant/message'
|
19
|
-
autoload :
|
19
|
+
autoload :Projector, 'lieutenant/projector'
|
20
20
|
autoload :VERSION, 'lieutenant/version'
|
21
21
|
|
22
22
|
module_function
|
data/lieutenant.gemspec
CHANGED
@@ -1,13 +1,12 @@
|
|
1
|
-
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
|
-
lib = File.expand_path('
|
3
|
+
lib = File.expand_path('./lib')
|
5
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
5
|
require 'lieutenant/version'
|
7
6
|
|
8
7
|
Gem::Specification.new do |spec|
|
9
8
|
spec.name = 'lieutenant'
|
10
|
-
spec.version = Lieutenant::VERSION
|
9
|
+
spec.version = "#{Lieutenant::VERSION}#{ENV['GEM_VERSION_SUFFIX']}"
|
11
10
|
spec.authors = ['Gabriel Teles']
|
12
11
|
spec.email = ['gab.teles@hotmail.com']
|
13
12
|
|
@@ -21,14 +20,5 @@ Gem::Specification.new do |spec|
|
|
21
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
21
|
spec.require_paths = ['lib']
|
23
22
|
|
24
|
-
spec.add_development_dependency 'bundler'
|
25
|
-
spec.add_development_dependency 'coveralls'
|
26
|
-
spec.add_development_dependency 'pry'
|
27
|
-
spec.add_development_dependency 'rake'
|
28
|
-
spec.add_development_dependency 'reek'
|
29
|
-
spec.add_development_dependency 'rspec'
|
30
|
-
spec.add_development_dependency 'rubocop'
|
31
|
-
spec.add_development_dependency 'simplecov'
|
32
|
-
spec.add_development_dependency 'yard'
|
33
23
|
spec.add_dependency 'activemodel'
|
34
24
|
end
|
metadata
CHANGED
@@ -1,141 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lieutenant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0.pre.alpha
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Teles
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: coveralls
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: pry
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rake
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: reek
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rubocop
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: simplecov
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: yard
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
13
|
- !ruby/object:Gem::Dependency
|
140
14
|
name: activemodel
|
141
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -160,7 +34,6 @@ files:
|
|
160
34
|
- ".gitignore"
|
161
35
|
- ".rspec"
|
162
36
|
- ".rubocop.yml"
|
163
|
-
- ".travis.yml"
|
164
37
|
- Gemfile
|
165
38
|
- README.md
|
166
39
|
- Rakefile
|
@@ -175,6 +48,7 @@ files:
|
|
175
48
|
- lib/lieutenant/config.rb
|
176
49
|
- lib/lieutenant/event.rb
|
177
50
|
- lib/lieutenant/event_bus.rb
|
51
|
+
- lib/lieutenant/event_bus/in_memory.rb
|
178
52
|
- lib/lieutenant/event_store.rb
|
179
53
|
- lib/lieutenant/event_store/in_memory.rb
|
180
54
|
- lib/lieutenant/exception.rb
|
@@ -182,7 +56,7 @@ files:
|
|
182
56
|
- lib/lieutenant/exception/concurrency_conflict.rb
|
183
57
|
- lib/lieutenant/exception/no_registered_handler.rb
|
184
58
|
- lib/lieutenant/message.rb
|
185
|
-
- lib/lieutenant/
|
59
|
+
- lib/lieutenant/projector.rb
|
186
60
|
- lib/lieutenant/version.rb
|
187
61
|
- lieutenant.gemspec
|
188
62
|
homepage: https://github.com/gabteles/lieutenant
|
@@ -199,12 +73,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
199
73
|
version: '0'
|
200
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
75
|
requirements:
|
202
|
-
- - "
|
76
|
+
- - ">"
|
203
77
|
- !ruby/object:Gem::Version
|
204
|
-
version:
|
78
|
+
version: 1.3.1
|
205
79
|
requirements: []
|
206
80
|
rubyforge_project:
|
207
|
-
rubygems_version: 2.6.
|
81
|
+
rubygems_version: 2.6.14
|
208
82
|
signing_key:
|
209
83
|
specification_version: 4
|
210
84
|
summary: CQRS/ES Toolkit to command them all
|
data/.travis.yml
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lieutenant
|
4
|
-
# Projection helper. Allows clean syntax to subscribe to events:
|
5
|
-
#
|
6
|
-
# module FooProjection
|
7
|
-
# include Lieutenant::Projection
|
8
|
-
#
|
9
|
-
# on(CreatedBarEvent) do |event|
|
10
|
-
# # ...
|
11
|
-
# end
|
12
|
-
# end
|
13
|
-
module Projection
|
14
|
-
def self.included(base)
|
15
|
-
base.class_eval do
|
16
|
-
extend Lieutenant::Projection
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# :reek:UtilityFunction
|
21
|
-
def on(*event_classes, &block)
|
22
|
-
Lieutenant.config.event_bus.subscribe(*event_classes, &block)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|