akasha 0.0.1 → 0.1.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/.rspec +1 -0
- data/.travis.yml +49 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +11 -1
- data/README.md +33 -13
- data/akasha.gemspec +1 -0
- data/lib/akasha.rb +1 -0
- data/lib/akasha/aggregate.rb +1 -1
- data/lib/akasha/aggregate/syntax_helpers.rb +2 -0
- data/lib/akasha/changeset.rb +12 -2
- data/lib/akasha/command_router.rb +36 -0
- data/lib/akasha/command_router/default_handler.rb +19 -0
- data/lib/akasha/version.rb +1 -1
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1294447dab3ae4202502a232dcc069d06dcdbf5d
|
4
|
+
data.tar.gz: 296cfc35578c3f15a90d55f0f0ed1db018458541
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b177423fce21ab067cee6c37f0d50e1d132056611791af3af17c56b2b8a2ba6ea20d76a11462e99459814b1ce24259ea86d01bc794818110da1ea49283fcbbc
|
7
|
+
data.tar.gz: 3cbe93b9aeafeca8b3541d01feaacfb6bdd0395bf3ed92d9be73a5ee7df3dfdb593deb8ad55e9d9647748f51a069ae881c9fd970aa473fc73f5087f63d012c3e
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.travis.yml
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Enables Travis to use their new container-based infrastructure
|
2
|
+
sudo: false
|
3
|
+
|
4
|
+
# Build for Ruby
|
5
|
+
language: ruby
|
6
|
+
|
7
|
+
# Enables caching for bundler
|
8
|
+
cache: bundler
|
9
|
+
|
10
|
+
# Passes arguments to bundle install (http://gembundler.com/man/bundle-install.1.html)
|
11
|
+
# bundler_args:
|
12
|
+
|
13
|
+
before_install:
|
14
|
+
- gem update --system
|
15
|
+
- gem update bundler
|
16
|
+
|
17
|
+
# Specify which ruby versions you wish to run your tests on, each version will be used
|
18
|
+
rvm:
|
19
|
+
- 2.2.9
|
20
|
+
- 2.3.6
|
21
|
+
- 2.4.3
|
22
|
+
- 2.5.0
|
23
|
+
|
24
|
+
# Define how to run your tests (defaults to `bundle exec rake` or `rake` depending on whether you have a `Gemfile`)
|
25
|
+
script: "bundle exec rake"
|
26
|
+
|
27
|
+
# Define tasks to be completed before and after tests run . Will allow folding of content on frontend
|
28
|
+
#before_script:
|
29
|
+
# - command_1
|
30
|
+
# - command_2
|
31
|
+
#
|
32
|
+
#after_script:
|
33
|
+
# - command_1
|
34
|
+
# - command_2
|
35
|
+
|
36
|
+
# Specify the recipients for email notification
|
37
|
+
#notifications:
|
38
|
+
# recipients:
|
39
|
+
# - email-address-1
|
40
|
+
# - email-address-2
|
41
|
+
|
42
|
+
# Disable email notifications
|
43
|
+
#notifications:
|
44
|
+
# disabled: true
|
45
|
+
|
46
|
+
# notifications:
|
47
|
+
# webhooks:
|
48
|
+
# urls:
|
49
|
+
# - https://webhooks.gitter.im/e/c6dbb9323007dfcf81df
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
|
4
|
+
## Version 0.1.0
|
5
|
+
|
6
|
+
* Cleaner syntax for adding events to changesets: `changeset.append(:it_happened, foo: 'bar')`.
|
7
|
+
* Support for command routing (`Akasha::CommandRouter`).
|
8
|
+
|
9
|
+
|
10
|
+
## Version 0.0.1
|
11
|
+
|
12
|
+
Initial release, basic functionality.
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,21 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
akasha (0.0
|
4
|
+
akasha (0.1.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
byebug (10.0.2)
|
10
|
+
coderay (1.1.2)
|
9
11
|
diff-lcs (1.3)
|
12
|
+
method_source (0.9.0)
|
13
|
+
pry (0.11.3)
|
14
|
+
coderay (~> 1.1.0)
|
15
|
+
method_source (~> 0.9.0)
|
16
|
+
pry-byebug (3.6.0)
|
17
|
+
byebug (~> 10.0)
|
18
|
+
pry (~> 0.10)
|
10
19
|
rake (10.5.0)
|
11
20
|
rspec (3.7.0)
|
12
21
|
rspec-core (~> 3.7.0)
|
@@ -29,6 +38,7 @@ PLATFORMS
|
|
29
38
|
DEPENDENCIES
|
30
39
|
akasha!
|
31
40
|
bundler (~> 1.16)
|
41
|
+
pry-byebug
|
32
42
|
rake (~> 10.0)
|
33
43
|
rspec (~> 3.7)
|
34
44
|
timecop
|
data/README.md
CHANGED
@@ -20,31 +20,51 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
+
The code below uses Sinatra to demonstrate how to use the library in a web application.
|
24
|
+
This library makes no assumptions about any web framework, you can use it in any way you see fit.
|
25
|
+
|
23
26
|
```ruby
|
24
27
|
require 'akasha'
|
25
|
-
|
28
|
+
require 'sinatra'
|
26
29
|
|
27
30
|
class User < Akasha::Aggregate
|
28
|
-
def sign_up(email,
|
29
|
-
changeset << Akasha::Event.new(:user_signed_up, email: email, password: password)
|
31
|
+
def sign_up(email:, password:, admin: false, **)
|
32
|
+
changeset << Akasha::Event.new(:user_signed_up, email: email, password: password, admin: admin)
|
30
33
|
end
|
31
34
|
|
32
|
-
def on_user_signed_up(email:, password:, **
|
35
|
+
def on_user_signed_up(email:, password:, admin:, **)
|
33
36
|
@email = email
|
34
37
|
@password = password
|
38
|
+
@admin = admin
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
42
|
+
|
43
|
+
before do
|
44
|
+
@router = Akasha::CommandRouter.new
|
45
|
+
|
46
|
+
# Aggregates will load from and save to in-memory storage.
|
47
|
+
repository = Akasha::Repository.new(Akasha::Storage::MemoryEventStore.new)
|
48
|
+
Akasha::Aggregate.connect!(repository)
|
49
|
+
|
50
|
+
# This is how you link commands to aggregates.
|
51
|
+
@router.register_default_route(:sign_up, User)
|
52
|
+
|
53
|
+
# Nearly identital to the default handling above but we're setting the admin
|
54
|
+
# flag to demo custom command handling.
|
55
|
+
@router.register_route(:sign_up_admin) do |aggregate_id, **data|
|
56
|
+
user = User.find_or_create(aggregate_id)
|
57
|
+
user.sign_up(email: data[:email], password: data[:password], admin: true)
|
58
|
+
user.save!
|
59
|
+
end
|
41
60
|
end
|
42
61
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
62
|
+
post '/users/:user_id' do # With CQRS client pass unique aggregate ids.
|
63
|
+
@router.route!(:sign_up,
|
64
|
+
params[:user_id],
|
65
|
+
email: params[:email],
|
66
|
+
password: params[:password])
|
67
|
+
'OK'
|
48
68
|
end
|
49
69
|
```
|
50
70
|
|
@@ -52,7 +72,7 @@ end
|
|
52
72
|
|
53
73
|
## Next steps
|
54
74
|
|
55
|
-
- [
|
75
|
+
- [x] Command routing (default and user-defined)
|
56
76
|
- [ ] EventHandler (relying only on Eventstore)
|
57
77
|
- [ ] HTTP Eventstore storage backend
|
58
78
|
- [ ] Namespacing for events and aggregates
|
data/akasha.gemspec
CHANGED
data/lib/akasha.rb
CHANGED
data/lib/akasha/aggregate.rb
CHANGED
@@ -8,7 +8,7 @@ module Akasha
|
|
8
8
|
#
|
9
9
|
# class User < Akasha::Aggregate
|
10
10
|
# def sign_up(email, password)
|
11
|
-
# changeset
|
11
|
+
# changeset.append(:user_signed_up, email: email, password: password)
|
12
12
|
# end
|
13
13
|
#
|
14
14
|
# def on_user_signed_up(email:, password:, **_)
|
data/lib/akasha/changeset.rb
CHANGED
@@ -10,8 +10,18 @@ module Akasha
|
|
10
10
|
end
|
11
11
|
|
12
12
|
# Adds an event to the changeset.
|
13
|
-
def
|
14
|
-
@events <<
|
13
|
+
def append(event_name, **data)
|
14
|
+
@events << Akasha::Event.new(event_name, **data)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns true if no changes recorded.
|
18
|
+
def empty?
|
19
|
+
@events.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
# Clears the changeset.
|
23
|
+
def clear!
|
24
|
+
@events = []
|
15
25
|
end
|
16
26
|
end
|
17
27
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'command_router/default_handler'
|
2
|
+
|
3
|
+
module Akasha
|
4
|
+
# Routes commands to their handlers.
|
5
|
+
class CommandRouter
|
6
|
+
# Raised when no corresponding target can be found for a command.
|
7
|
+
NotFoundError = Class.new(RuntimeError)
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@routes = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Registers a custom route, specifying either a lambda or a block.
|
14
|
+
# If both lambda and block are specified, lambda takes precedence.
|
15
|
+
def register_route(command, lambda = nil, &block)
|
16
|
+
callable = lambda || block
|
17
|
+
@routes[command] = callable
|
18
|
+
end
|
19
|
+
|
20
|
+
# Registers a default route, mapping a command to an aggregate class.
|
21
|
+
# As a result, when `#route!` is called for that command, the aggregate
|
22
|
+
# will be loaded from repository, the command will be sent to the object
|
23
|
+
# to invoke the object's method, and finally the aggregate will be saved.
|
24
|
+
def register_default_route(command, aggregate_class)
|
25
|
+
register_route(command, DefaultHandler.new(aggregate_class))
|
26
|
+
end
|
27
|
+
|
28
|
+
# Routes a command to the registered target.
|
29
|
+
# Raises NotFoundError if no corresponding target can be found.
|
30
|
+
def route!(command, aggregate_id, **data)
|
31
|
+
handler = @routes[command]
|
32
|
+
return handler.call(command, aggregate_id, **data) if handler
|
33
|
+
raise NotFoundError, "Target for command #{command.inspect} not found"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Akasha
|
2
|
+
class CommandRouter
|
3
|
+
# Default command handler.
|
4
|
+
# Works by loading aggregate from the repo by id,
|
5
|
+
# invoking its method `command`, passing all data,
|
6
|
+
# and saving changes to the aggregate in the end.
|
7
|
+
class DefaultHandler
|
8
|
+
def initialize(klass)
|
9
|
+
@klass = klass
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(command, aggregate_id, **data)
|
13
|
+
aggregate = @klass.find_or_create(aggregate_id)
|
14
|
+
aggregate.public_send(command, **data)
|
15
|
+
aggregate.save!
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/akasha/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: akasha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcin Bilski
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-06-
|
11
|
+
date: 2018-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-byebug
|
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'
|
69
83
|
description: A simple CQRS library for Ruby.
|
70
84
|
email:
|
71
85
|
- marcin@tooploox.com
|
@@ -74,8 +88,11 @@ extensions: []
|
|
74
88
|
extra_rdoc_files: []
|
75
89
|
files:
|
76
90
|
- ".gitignore"
|
91
|
+
- ".rspec"
|
77
92
|
- ".rubocop.yml"
|
78
93
|
- ".ruby-version"
|
94
|
+
- ".travis.yml"
|
95
|
+
- CHANGELOG.md
|
79
96
|
- Gemfile
|
80
97
|
- Gemfile.lock
|
81
98
|
- LICENSE.txt
|
@@ -88,6 +105,8 @@ files:
|
|
88
105
|
- lib/akasha/aggregate.rb
|
89
106
|
- lib/akasha/aggregate/syntax_helpers.rb
|
90
107
|
- lib/akasha/changeset.rb
|
108
|
+
- lib/akasha/command_router.rb
|
109
|
+
- lib/akasha/command_router/default_handler.rb
|
91
110
|
- lib/akasha/event.rb
|
92
111
|
- lib/akasha/repository.rb
|
93
112
|
- lib/akasha/storage/memory_event_store.rb
|