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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c13d7331d61d26a8ec7a9c816a25b959d2d94466
4
- data.tar.gz: f26f9cf92f4a8064078859bd488a5cb15eb3954b
3
+ metadata.gz: c089fabb4e4b27e50920ed0ba094a7e190da35e4
4
+ data.tar.gz: 570e7d26edeb138f2c08cc1c27ba0b30d7cca582
5
5
  SHA512:
6
- metadata.gz: 7f85b854951dd7e9556186ba9a173331cbd7cef3dd45e23e4a8e52a27508ac2d2a78a67cb2279dee7fe270fd85bb552d621d4c0d3c174b5fb6f90ec901ce22fd
7
- data.tar.gz: 1ca3adbc3fb5fdc021b00f2621d1b65b722f724f7fa7dd554a650a0cef32167a64e48d1a54adddcdb6bc26d795ffa62a506d5e920de50cd7b22e20eb3b9f3b2e
6
+ metadata.gz: 4d6ed77c3745f2413fa2c9cfcdcb835e4c029314a27a63596995d4f29c1de812ce3be6e03e3bf4d7b1e63107361ae7218165b1a2c56ca921eea84f61d945dc15
7
+ data.tar.gz: 5c53dc7c195b2543317ec7954ed1a17474b7f445bd5cdc917a2715dd84200371b87bfc6e1b2b87ac13a42a6730d4c2abdf116c623fa6a108cc40e4f9930aaf5f
data/.gitignore CHANGED
@@ -7,5 +7,6 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  Gemfile.lock
10
+ .byebug_history
10
11
  # rspec failure tracking
11
12
  .rspec_status
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.1
2
+ TargetRubyVersion: 2.2
3
3
 
4
4
  Metrics/LineLength:
5
5
  Max: 120
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
- [![Coverage Status](https://coveralls.io/repos/github/gabteles/lieutenant/badge.svg?branch=master)](https://coveralls.io/github/gabteles/lieutenant?branch=master)
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
- - [Projections](#projections)
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 dependes on all the configuration components, so be sure to config them before calling it. See [Configuration](#configuration).
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 into the event stream. You should not worry about them, we use them internally ;)
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
- # attr_accessor :aggregate_id (Meeting room's UUID)
251
- # attr_accessor :sequence_number
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
- ### Projections
275
+ ### Projectors
276
276
 
277
- The Projections listens to events it is interested in and updates read models
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::Projection`.
279
+ it, just include `Lieutenant::Projector`.
280
280
 
281
281
  ```ruby
282
- module MeetingRoomProjection
283
- include Lieutenant::Projection
282
+ module MeetingRoomProjector
283
+ include Lieutenant::Projector
284
284
 
285
- on(MeetingRoomCreated) do |event|
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
- on(MeetingScheduled) do |event|
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.push({
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
- meeting_room.save!
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.event_store(Lieutenant::EventStore::InMemory)
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.event_store(Lieutenant::EventStore::InMemory)
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
 
@@ -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
@@ -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
- # :reek:BooleanParameter
11
- def event_store(implementation = false)
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
@@ -9,11 +9,11 @@ module Lieutenant
9
9
  end
10
10
  end
11
11
 
12
- attr_reader :aggregate_id, :sequence_number
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
@@ -2,23 +2,7 @@
2
2
 
3
3
  module Lieutenant
4
4
  # Publishes and receives messages from the aggregates updates
5
- class EventBus
6
- def initialize
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
- PREPARE_EVENTS[aggregate_id, events, expected_version].tap do |final_events|
17
- store.persist(final_events)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lieutenant
4
- VERSION = '0.2.0'.freeze
4
+ VERSION = '0.3.0'.freeze
5
5
  end
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 :Projection, 'lieutenant/projection'
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('../lib', __FILE__)
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.2.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-02-05 00:00:00.000000000 Z
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/projection.rb
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: '0'
78
+ version: 1.3.1
205
79
  requirements: []
206
80
  rubyforge_project:
207
- rubygems_version: 2.6.11
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,11 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.1
5
- - 2.2
6
- - 2.3.0
7
- - 2.4.1
8
- - ruby-head
9
- before_install: gem install bundler -v 1.16.0
10
- script:
11
- - bundle exec rake fulltest
@@ -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