evey 0.1.0 → 0.2.0

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
  SHA256:
3
- metadata.gz: b836bd65b40b93b1d72e84a0e028f0e19e07b044cb0adb2b4234e081f1815ec1
4
- data.tar.gz: 797b8537f21ea61eabd201821edbccac3c3bc6960aa089e88f5f1b65b82330b4
3
+ metadata.gz: ea6cdb42a613f053cf4f4d08b8ecbd8c0648f72d69ea70054a8f5f7072c0c1f9
4
+ data.tar.gz: 3e07e0a600b608e2568050d46415b8713657637e768665a0c35ce7a46280389e
5
5
  SHA512:
6
- metadata.gz: cc46d974d5567c2a560de6c88295d89b9b437e7ec3e59318df9eb3544d184ef8a4d7a607ba4aa183e3125b0b6bcfa326d2d1af10f3fde562b5144070447df2ba
7
- data.tar.gz: 88f0f800fb198e4d1f2083cbbe26a9524956346ac0da50535da066492a310a74a63e09e789fe458ca6dee95bf163eec0498acc115b46cdf5e47eda700b6588eb
6
+ metadata.gz: fd266ca53d16aa50fa25fbba1333c350619f1b1d40aeb9de3491686227e7a271f2c082ae2db259dfb8b6abe92b631cb942c41f736ff82f46a8774ee0dc5e1acb
7
+ data.tar.gz: '008745e3ac4fb77c091d9d6d55a5258fc786d9a9c89c9a795a0abc2f27c32338d9d27a645f1499ebcda4433392f38e0219fc7c258c0a10ce5006f02e92c64cce'
data/.gitignore CHANGED
@@ -9,3 +9,5 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ evey-*.gem
13
+ spec/support/dummy_app/log/**/*.log
data/CITATIONS.txt ADDED
@@ -0,0 +1,22 @@
1
+ https://github.com/kickstarter/event-sourcing-rails-todo-app-demo
2
+
3
+ Copyright (c) 2017 Kickstarter, PBC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Gemfile.lock ADDED
@@ -0,0 +1,221 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ evey (0.1.0)
5
+ activejob
6
+ activerecord
7
+ activesupport
8
+ kix
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ actioncable (6.1.3.1)
14
+ actionpack (= 6.1.3.1)
15
+ activesupport (= 6.1.3.1)
16
+ nio4r (~> 2.0)
17
+ websocket-driver (>= 0.6.1)
18
+ actionmailbox (6.1.3.1)
19
+ actionpack (= 6.1.3.1)
20
+ activejob (= 6.1.3.1)
21
+ activerecord (= 6.1.3.1)
22
+ activestorage (= 6.1.3.1)
23
+ activesupport (= 6.1.3.1)
24
+ mail (>= 2.7.1)
25
+ actionmailer (6.1.3.1)
26
+ actionpack (= 6.1.3.1)
27
+ actionview (= 6.1.3.1)
28
+ activejob (= 6.1.3.1)
29
+ activesupport (= 6.1.3.1)
30
+ mail (~> 2.5, >= 2.5.4)
31
+ rails-dom-testing (~> 2.0)
32
+ actionpack (6.1.3.1)
33
+ actionview (= 6.1.3.1)
34
+ activesupport (= 6.1.3.1)
35
+ rack (~> 2.0, >= 2.0.9)
36
+ rack-test (>= 0.6.3)
37
+ rails-dom-testing (~> 2.0)
38
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
39
+ actiontext (6.1.3.1)
40
+ actionpack (= 6.1.3.1)
41
+ activerecord (= 6.1.3.1)
42
+ activestorage (= 6.1.3.1)
43
+ activesupport (= 6.1.3.1)
44
+ nokogiri (>= 1.8.5)
45
+ actionview (6.1.3.1)
46
+ activesupport (= 6.1.3.1)
47
+ builder (~> 3.1)
48
+ erubi (~> 1.4)
49
+ rails-dom-testing (~> 2.0)
50
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
51
+ activejob (6.1.3.1)
52
+ activesupport (= 6.1.3.1)
53
+ globalid (>= 0.3.6)
54
+ activemodel (6.1.3.1)
55
+ activesupport (= 6.1.3.1)
56
+ activerecord (6.1.3.1)
57
+ activemodel (= 6.1.3.1)
58
+ activesupport (= 6.1.3.1)
59
+ activestorage (6.1.3.1)
60
+ actionpack (= 6.1.3.1)
61
+ activejob (= 6.1.3.1)
62
+ activerecord (= 6.1.3.1)
63
+ activesupport (= 6.1.3.1)
64
+ marcel (~> 1.0.0)
65
+ mini_mime (~> 1.0.2)
66
+ activesupport (6.1.3.1)
67
+ concurrent-ruby (~> 1.0, >= 1.0.2)
68
+ i18n (>= 1.6, < 2)
69
+ minitest (>= 5.1)
70
+ tzinfo (~> 2.0)
71
+ zeitwerk (~> 2.3)
72
+ ast (2.4.2)
73
+ builder (3.2.4)
74
+ coderay (1.1.3)
75
+ concurrent-ruby (1.1.8)
76
+ crass (1.0.6)
77
+ diff-lcs (1.4.4)
78
+ docile (1.3.5)
79
+ erubi (1.10.0)
80
+ factory_bot (6.1.0)
81
+ activesupport (>= 5.0.0)
82
+ factory_bot_rails (6.1.0)
83
+ factory_bot (~> 6.1.0)
84
+ railties (>= 5.0.0)
85
+ globalid (0.4.2)
86
+ activesupport (>= 4.2.0)
87
+ i18n (1.8.10)
88
+ concurrent-ruby (~> 1.0)
89
+ kix (1.0.0)
90
+ activesupport
91
+ loofah (2.9.1)
92
+ crass (~> 1.0.2)
93
+ nokogiri (>= 1.5.9)
94
+ mail (2.7.1)
95
+ mini_mime (>= 0.1.1)
96
+ marcel (1.0.1)
97
+ method_source (1.0.0)
98
+ mini_mime (1.0.3)
99
+ minitest (5.14.4)
100
+ nio4r (2.5.7)
101
+ nokogiri (1.11.3-x86_64-linux)
102
+ racc (~> 1.4)
103
+ parallel (1.20.1)
104
+ parser (3.0.1.0)
105
+ ast (~> 2.4.1)
106
+ pg (1.2.3)
107
+ pry (0.14.1)
108
+ coderay (~> 1.1)
109
+ method_source (~> 1.0)
110
+ racc (1.5.2)
111
+ rack (2.2.3)
112
+ rack-test (1.1.0)
113
+ rack (>= 1.0, < 3)
114
+ rails (6.1.3.1)
115
+ actioncable (= 6.1.3.1)
116
+ actionmailbox (= 6.1.3.1)
117
+ actionmailer (= 6.1.3.1)
118
+ actionpack (= 6.1.3.1)
119
+ actiontext (= 6.1.3.1)
120
+ actionview (= 6.1.3.1)
121
+ activejob (= 6.1.3.1)
122
+ activemodel (= 6.1.3.1)
123
+ activerecord (= 6.1.3.1)
124
+ activestorage (= 6.1.3.1)
125
+ activesupport (= 6.1.3.1)
126
+ bundler (>= 1.15.0)
127
+ railties (= 6.1.3.1)
128
+ sprockets-rails (>= 2.0.0)
129
+ rails-dom-testing (2.0.3)
130
+ activesupport (>= 4.2.0)
131
+ nokogiri (>= 1.6)
132
+ rails-html-sanitizer (1.3.0)
133
+ loofah (~> 2.3)
134
+ railties (6.1.3.1)
135
+ actionpack (= 6.1.3.1)
136
+ activesupport (= 6.1.3.1)
137
+ method_source
138
+ rake (>= 0.8.7)
139
+ thor (~> 1.0)
140
+ rainbow (3.0.0)
141
+ rake (12.3.3)
142
+ regexp_parser (2.1.1)
143
+ rexml (3.2.5)
144
+ rspec (3.10.0)
145
+ rspec-core (~> 3.10.0)
146
+ rspec-expectations (~> 3.10.0)
147
+ rspec-mocks (~> 3.10.0)
148
+ rspec-core (3.10.1)
149
+ rspec-support (~> 3.10.0)
150
+ rspec-expectations (3.10.1)
151
+ diff-lcs (>= 1.2.0, < 2.0)
152
+ rspec-support (~> 3.10.0)
153
+ rspec-mocks (3.10.2)
154
+ diff-lcs (>= 1.2.0, < 2.0)
155
+ rspec-support (~> 3.10.0)
156
+ rspec-rails (5.0.1)
157
+ actionpack (>= 5.2)
158
+ activesupport (>= 5.2)
159
+ railties (>= 5.2)
160
+ rspec-core (~> 3.10)
161
+ rspec-expectations (~> 3.10)
162
+ rspec-mocks (~> 3.10)
163
+ rspec-support (~> 3.10)
164
+ rspec-support (3.10.2)
165
+ rubocop (1.12.1)
166
+ parallel (~> 1.10)
167
+ parser (>= 3.0.0.0)
168
+ rainbow (>= 2.2.2, < 4.0)
169
+ regexp_parser (>= 1.8, < 3.0)
170
+ rexml
171
+ rubocop-ast (>= 1.2.0, < 2.0)
172
+ ruby-progressbar (~> 1.7)
173
+ unicode-display_width (>= 1.4.0, < 3.0)
174
+ rubocop-ast (1.4.1)
175
+ parser (>= 2.7.1.5)
176
+ rubocop-performance (1.10.1)
177
+ rubocop (>= 0.90.0, < 2.0)
178
+ rubocop-ast (>= 0.4.0)
179
+ ruby-progressbar (1.11.0)
180
+ simplecov (0.21.2)
181
+ docile (~> 1.1)
182
+ simplecov-html (~> 0.11)
183
+ simplecov_json_formatter (~> 0.1)
184
+ simplecov-html (0.12.3)
185
+ simplecov_json_formatter (0.1.2)
186
+ sprockets (4.0.2)
187
+ concurrent-ruby (~> 1.0)
188
+ rack (> 1, < 3)
189
+ sprockets-rails (3.2.2)
190
+ actionpack (>= 4.0)
191
+ activesupport (>= 4.0)
192
+ sprockets (>= 3.0.0)
193
+ standard (1.0.5)
194
+ rubocop (= 1.12.1)
195
+ rubocop-performance (= 1.10.1)
196
+ thor (1.1.0)
197
+ tzinfo (2.0.4)
198
+ concurrent-ruby (~> 1.0)
199
+ unicode-display_width (2.0.0)
200
+ websocket-driver (0.7.3)
201
+ websocket-extensions (>= 0.1.0)
202
+ websocket-extensions (0.1.5)
203
+ zeitwerk (2.4.2)
204
+
205
+ PLATFORMS
206
+ x86_64-linux
207
+
208
+ DEPENDENCIES
209
+ evey!
210
+ factory_bot_rails
211
+ pg
212
+ pry
213
+ rails
214
+ rake (~> 12.0)
215
+ rspec (~> 3.0)
216
+ rspec-rails
217
+ simplecov
218
+ standard
219
+
220
+ BUNDLED WITH
221
+ 2.2.15
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2021 TODO: Write your name
3
+ Copyright (c) 2021 John Thomas
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # Evey
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/evey`. 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
+ Rails event sourcing made simple.
6
4
 
7
5
  ## Installation
8
6
 
@@ -22,7 +20,7 @@ Or install it yourself as:
22
20
 
23
21
  ## Usage
24
22
 
25
- TODO: Write usage instructions here
23
+ Probably don't.
26
24
 
27
25
  ## Development
28
26
 
@@ -32,7 +30,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
32
30
 
33
31
  ## Contributing
34
32
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/evey.
33
+ Bug reports and pull requests are welcome on GitHub at https://github.com/thomas07vt/evey.
36
34
 
37
35
 
38
36
  ## License
data/evey.gemspec CHANGED
@@ -9,6 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.summary = %q{Simple Event sourcing coming soon.}
10
10
  spec.description = %q{Simple event sourcing.}
11
11
  spec.homepage = "https://github.com"
12
+ spec.homepage = "https://github.com/thomas07vt/serializable_rails"
12
13
  spec.license = "MIT"
13
14
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
15
 
@@ -23,4 +24,18 @@ Gem::Specification.new do |spec|
23
24
  spec.bindir = "exe"
24
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
26
  spec.require_paths = ["lib"]
27
+
28
+ spec.add_dependency "kix"
29
+ spec.add_dependency "activejob"
30
+ spec.add_dependency "activerecord"
31
+ spec.add_dependency "activesupport"
32
+
33
+ spec.add_development_dependency "pry"
34
+ spec.add_development_dependency "rails"
35
+ spec.add_development_dependency "rspec"
36
+ spec.add_development_dependency "rspec-rails"
37
+ spec.add_development_dependency "simplecov"
38
+ spec.add_development_dependency "standard"
39
+ spec.add_development_dependency "pg"
40
+ spec.add_development_dependency "factory_bot_rails"
26
41
  end
data/lib/evey.rb CHANGED
@@ -1,6 +1,23 @@
1
- require "evey/version"
2
-
3
1
  module Evey
4
- class Error < StandardError; end
5
- # Your code goes here...
2
+ def self.table_name_prefix
3
+ "evey_"
4
+ end
6
5
  end
6
+
7
+ require "kix"
8
+ require "active_job"
9
+ require "active_record"
10
+ require "active_support"
11
+ require "active_support/core_ext/object/json.rb"
12
+
13
+ require "rails/generators"
14
+ require "rails/generators/migration"
15
+
16
+ require "evey/types.rb"
17
+ require "evey/types/association.rb"
18
+ require "evey/event_serializer.rb"
19
+ require "evey/event.rb"
20
+ require "evey/version.rb"
21
+ require "evey/reactor.rb"
22
+ require "evey/dispatcher.rb"
23
+ require "evey/reactor_job.rb"
@@ -0,0 +1,96 @@
1
+ class Evey::Dispatcher
2
+ def self.enable!
3
+ @disabled = false
4
+ end
5
+
6
+ def self.disable!
7
+ @disabled = true
8
+ end
9
+
10
+ def self.enabled?
11
+ @disabled != true
12
+ end
13
+
14
+ def self.configure
15
+ if block_given?
16
+ @rules = nil
17
+ yield self
18
+ end
19
+ end
20
+
21
+ # Register Reactors to Events.
22
+ # * Reactors registered with `sync` will be triggered synchronously
23
+ # * Reactors registered with `async` will be triggered asynchronously via a Sidekiq Job
24
+ #
25
+ # Example:
26
+ #
27
+ # on BaseEvent, sync: LogEvent, async: TrackEvent
28
+ # on PledgeCancelled, PaymentFailed, async: [NotifyAdmin, CreateTask]
29
+ # on [PledgeCancelled, PaymentFailed], async: [NotifyAdmin, CreateTask]
30
+ #
31
+ def self.on(*events, sync: [], async: [])
32
+ rules.register(events: events.flatten, sync: Array(sync), async: Array(async))
33
+ end
34
+
35
+ # Dispatches events to matching Reactors once.
36
+ # Called by all events after they are created.
37
+ def self.dispatch(event)
38
+ return unless enabled?
39
+
40
+ reactors = rules.for(event)
41
+ reactors.sync.each { |reactor| reactor.call(event) }
42
+ reactors.async.each { |reactor| Evey::ReactorJob.perform_later(event, reactor.to_s) }
43
+ end
44
+
45
+ def self.rules
46
+ @rules ||= RuleSet.new
47
+ end
48
+
49
+ class RuleSet
50
+ def initialize
51
+ @rules ||= Hash.new { |h, k| h[k] = ReactorSet.new }
52
+ end
53
+
54
+ # Register events with their sync and async Reactors
55
+ def register(events:, sync:, async:)
56
+ events.each do |event|
57
+ @rules[event].add_sync sync
58
+ @rules[event].add_async async
59
+ end
60
+ end
61
+
62
+ # Return a ReactorSet containing all Reactors matching an Event
63
+ def for(event)
64
+ reactors = ReactorSet.new
65
+
66
+ @rules.each do |event_class, rule|
67
+ if event.class == event_class
68
+ reactors.add_sync rule.sync
69
+ reactors.add_async rule.async
70
+ end
71
+ end
72
+
73
+ reactors
74
+ end
75
+ end
76
+
77
+ # Contains sync and async reactors. Used to:
78
+ # * store reactors via Rules#register
79
+ # * return a set of matching reactors with Rules#for
80
+ class ReactorSet
81
+ attr_reader :sync, :async
82
+
83
+ def initialize
84
+ @sync = Set.new
85
+ @async = Set.new
86
+ end
87
+
88
+ def add_sync(reactors)
89
+ @sync += reactors
90
+ end
91
+
92
+ def add_async(reactors)
93
+ @async += reactors
94
+ end
95
+ end
96
+ end
data/lib/evey/event.rb ADDED
@@ -0,0 +1,151 @@
1
+ class Evey::Event < ActiveRecord::Base
2
+ include Kix::Serializable
3
+
4
+ belongs_to :user, optional: true
5
+
6
+ before_create :apply_and_persist
7
+ after_create_commit :dispatch
8
+
9
+ attribute :aggregates, Evey::Types::Association.new
10
+ attribute :associations, Evey::Types::Association.new
11
+
12
+ class << self
13
+ def registered_events
14
+ @registered_events ||= {}
15
+ end
16
+
17
+ def inherited(klass)
18
+ super
19
+ ::Evey::Event.registered_events[klass.event_name] = klass
20
+ klass.request_hook(&@request_hook) if @request_hook
21
+ end
22
+
23
+ def aggregates(*ags)
24
+ @aggregates ||= []
25
+
26
+ ags.map(&:to_s).each do |ag|
27
+ next if @aggregates.include?(ag)
28
+
29
+ @aggregates << ag
30
+
31
+ define_method ag do
32
+ self.aggregates ||= {}
33
+ self.aggregates[ag]
34
+ end
35
+
36
+ define_method "#{ag}=" do |arg|
37
+ self.aggregates ||= {}
38
+ self.aggregates[ag] = arg
39
+ end
40
+ end
41
+
42
+ @aggregates
43
+ end
44
+ alias_method :aggregate, :aggregates
45
+
46
+ def associations(*assoces)
47
+ @associations ||= []
48
+
49
+ assoces.map(&:to_s).each do |assoc|
50
+ next if @associations.include?(assoc)
51
+
52
+ @associations << assoc
53
+
54
+ define_method assoc do
55
+ self.associations ||= {}
56
+ self.associations[assoc]
57
+ end
58
+
59
+ define_method "#{assoc}=" do |arg|
60
+ self.associations ||= {}
61
+ self.associations[assoc] = arg
62
+ end
63
+ end
64
+
65
+ @associations
66
+ end
67
+ alias_method :association, :associations
68
+
69
+ def data_attributes(*attrs)
70
+ @data_attributes ||= []
71
+
72
+ attrs.map(&:to_s).each do |attr|
73
+ @data_attributes << attr unless @data_attributes.include?(attr)
74
+
75
+ define_method attr do
76
+ self.data ||= {}
77
+ self.data[attr]
78
+ end
79
+
80
+ define_method "#{attr}=" do |arg|
81
+ self.data ||= {}
82
+ self.data[attr] = arg
83
+ end
84
+
85
+ define_method "#{attr}_was_set?" do
86
+ self.data ||= {}
87
+ self.data.key?(attr)
88
+ end
89
+ end
90
+
91
+ @data_attributes
92
+ end
93
+
94
+ def request_hook(&block)
95
+ @request_hook = block if block.present?
96
+ @request_hook
97
+ end
98
+
99
+ # Underscored class name by default. ex: "post/updated"
100
+ # Used when sending events to the data pipeline
101
+ def event_name
102
+ name.underscore
103
+ end
104
+ end
105
+
106
+ delegate :event_name, to: :class
107
+
108
+ after_initialize do
109
+ self.data ||= {}
110
+ self.associations ||= {}
111
+ self.aggregates ||= {}
112
+ self.metadata ||= {}
113
+ self.type ||= self.class.name
114
+ end
115
+
116
+ def apply
117
+ end
118
+
119
+ def request_hook
120
+ self.class.request_hook
121
+ end
122
+
123
+ def errors_as_json
124
+ return {} if errors.blank?
125
+
126
+ errors.as_json.merge(aggregate_errors_as_json)
127
+ end
128
+
129
+ private
130
+
131
+ def apply_and_persist
132
+ aggregates.values.map(&:lock!)
133
+ apply
134
+ aggregates.map do |name, aggregate|
135
+ errors.add(name, 'is invalid') unless aggregate.save
136
+ end
137
+
138
+ throw :abort if errors.any?
139
+ end
140
+
141
+ def dispatch
142
+ Evey::Dispatcher.dispatch(self)
143
+ end
144
+
145
+ def aggregate_errors_as_json
146
+ aggregates.each_with_object({}) do |array, hash|
147
+ name, aggregate = array
148
+ hash[name.to_sym] = aggregate.errors.as_json if aggregate.errors.present?
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,10 @@
1
+ class Evey::EventSerializer < Kix::Serializer
2
+ attributes :type, :data, :metadata, :aggregates, :associations,
3
+ :created_at, :updated_at, :errors
4
+
5
+ def errors
6
+ throw(:skip) if _object.errors.empty?
7
+
8
+ _object.errors_as_json
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ class Evey::Reactor
2
+ def self.call(event)
3
+ new(event).call
4
+ end
5
+
6
+ attr_accessor :event
7
+
8
+ def initialize(event)
9
+ @event = event
10
+ end
11
+
12
+ def call
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ class Evey::ReactorJob < ActiveJob::Base
2
+ def perform(event, reactor_class)
3
+ reactor = reactor_class.constantize
4
+
5
+ reactor.call(event)
6
+ end
7
+ end
data/lib/evey/types.rb ADDED
@@ -0,0 +1,2 @@
1
+ module Evey::Types
2
+ end
@@ -0,0 +1,31 @@
1
+ class Evey::Types::Association < ActiveRecord::Type::Value
2
+ def type
3
+ :json
4
+ end
5
+
6
+ def cast(hash)
7
+ return if hash.nil?
8
+
9
+ hash.transform_values { |v| GlobalID::Locator.locate(v) }
10
+ end
11
+
12
+ def deserialize(hash)
13
+ return cast(hash) unless hash.is_a?(::String)
14
+
15
+ cast(decode_value(hash))
16
+ end
17
+
18
+ def serialize(hash)
19
+ return if hash.nil?
20
+
21
+ ::ActiveSupport::JSON.encode(hash.transform_values { |v| v.to_global_id.to_s })
22
+ end
23
+
24
+ private
25
+
26
+ def decode_value(value)
27
+ ::ActiveSupport::JSON.decode(value)
28
+ rescue StandardError
29
+ nil
30
+ end
31
+ end
data/lib/evey/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Evey
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,10 @@
1
+ module Evey
2
+ class InstallGenerator < Rails::Generators::Base
3
+ source_root File.expand_path(__dir__)
4
+
5
+ def create_migration
6
+ template "migration.erb", "db/migrate/#{Time.current.strftime("%Y%m%d%H%M%S")}_create_evey_events.rb"
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,16 @@
1
+ class CreateEveyEvents < ActiveRecord::Migration::Current
2
+ def change
3
+ create_table :evey_events do |t|
4
+ t.string :type, null: false
5
+ t.bigint :user_id
6
+ t.jsonb :data
7
+ t.jsonb :metadata
8
+ t.jsonb :aggregates
9
+ t.jsonb :associations
10
+
11
+ t.timestamps
12
+ end
13
+
14
+ add_index :evey_events, :user_id
15
+ end
16
+ end
metadata CHANGED
@@ -1,15 +1,183 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evey
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
  - John Thomas
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-19 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-04-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kix
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
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: activejob
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
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: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
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: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
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: pry
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: rails
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: rspec
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: rspec-rails
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: simplecov
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
+ - !ruby/object:Gem::Dependency
140
+ name: standard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: pg
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: factory_bot_rails
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
13
181
  description: Simple event sourcing.
14
182
  email:
15
183
  - thomas07@vt.edu
@@ -20,7 +188,9 @@ files:
20
188
  - ".gitignore"
21
189
  - ".rspec"
22
190
  - ".travis.yml"
191
+ - CITATIONS.txt
23
192
  - Gemfile
193
+ - Gemfile.lock
24
194
  - LICENSE.txt
25
195
  - README.md
26
196
  - Rakefile
@@ -28,12 +198,21 @@ files:
28
198
  - bin/setup
29
199
  - evey.gemspec
30
200
  - lib/evey.rb
201
+ - lib/evey/dispatcher.rb
202
+ - lib/evey/event.rb
203
+ - lib/evey/event_serializer.rb
204
+ - lib/evey/reactor.rb
205
+ - lib/evey/reactor_job.rb
206
+ - lib/evey/types.rb
207
+ - lib/evey/types/association.rb
31
208
  - lib/evey/version.rb
32
- homepage: https://github.com
209
+ - lib/generators/evey/install_generator.rb
210
+ - lib/generators/evey/migration.erb
211
+ homepage: https://github.com/thomas07vt/serializable_rails
33
212
  licenses:
34
213
  - MIT
35
214
  metadata:
36
- homepage_uri: https://github.com
215
+ homepage_uri: https://github.com/thomas07vt/serializable_rails
37
216
  source_code_uri: https://github.com
38
217
  post_install_message:
39
218
  rdoc_options: []
@@ -50,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
50
229
  - !ruby/object:Gem::Version
51
230
  version: '0'
52
231
  requirements: []
53
- rubygems_version: 3.0.8
232
+ rubygems_version: 3.2.15
54
233
  signing_key:
55
234
  specification_version: 4
56
235
  summary: Simple Event sourcing coming soon.