ruby_event_store 2.2.0 → 2.4.1
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/lib/ruby_event_store/batch_enumerator.rb +3 -3
- data/lib/ruby_event_store/broker.rb +5 -4
- data/lib/ruby_event_store/client.rb +75 -46
- data/lib/ruby_event_store/composed_dispatcher.rb +1 -3
- data/lib/ruby_event_store/correlated_commands.rb +4 -15
- data/lib/ruby_event_store/errors.rb +11 -10
- data/lib/ruby_event_store/event.rb +9 -14
- data/lib/ruby_event_store/expected_version.rb +3 -7
- data/lib/ruby_event_store/in_memory_repository.rb +100 -37
- data/lib/ruby_event_store/instrumented_dispatcher.rb +11 -2
- data/lib/ruby_event_store/instrumented_repository.rb +13 -8
- data/lib/ruby_event_store/link_by_metadata.rb +4 -21
- data/lib/ruby_event_store/mappers/default.rb +6 -4
- data/lib/ruby_event_store/mappers/encryption_key.rb +7 -16
- data/lib/ruby_event_store/mappers/encryption_mapper.rb +6 -6
- data/lib/ruby_event_store/mappers/forgotten_data.rb +1 -1
- data/lib/ruby_event_store/mappers/in_memory_encryption_key_repository.rb +1 -1
- data/lib/ruby_event_store/mappers/null_mapper.rb +0 -1
- data/lib/ruby_event_store/mappers/pipeline.rb +3 -10
- data/lib/ruby_event_store/mappers/pipeline_mapper.rb +1 -0
- data/lib/ruby_event_store/mappers/transformation/domain_event.rb +23 -13
- data/lib/ruby_event_store/mappers/transformation/encryption.rb +21 -25
- data/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb +6 -5
- data/lib/ruby_event_store/mappers/transformation/stringify_metadata_keys.rb +6 -5
- data/lib/ruby_event_store/mappers/transformation/symbolize_metadata_keys.rb +6 -5
- data/lib/ruby_event_store/mappers/transformation/upcast.rb +2 -6
- data/lib/ruby_event_store/metadata.rb +46 -17
- data/lib/ruby_event_store/projection.rb +12 -20
- data/lib/ruby_event_store/record.rb +14 -26
- data/lib/ruby_event_store/serialized_record.rb +14 -26
- data/lib/ruby_event_store/serializers/yaml.rb +17 -0
- data/lib/ruby_event_store/spec/broker_lint.rb +38 -28
- data/lib/ruby_event_store/spec/event_lint.rb +10 -10
- data/lib/ruby_event_store/spec/event_repository_lint.rb +745 -741
- data/lib/ruby_event_store/spec/mapper_lint.rb +2 -2
- data/lib/ruby_event_store/spec/subscriptions_lint.rb +58 -57
- data/lib/ruby_event_store/specification.rb +20 -16
- data/lib/ruby_event_store/specification_reader.rb +2 -3
- data/lib/ruby_event_store/specification_result.rb +52 -46
- data/lib/ruby_event_store/stream.rb +3 -7
- data/lib/ruby_event_store/subscriptions.rb +14 -15
- data/lib/ruby_event_store/transform_keys.rb +1 -1
- data/lib/ruby_event_store/version.rb +1 -1
- data/lib/ruby_event_store.rb +44 -43
- metadata +6 -4
@@ -13,11 +13,20 @@ module RubyEventStore
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
16
|
+
def method_missing(method_name, *arguments, **keyword_arguments, &block)
|
17
|
+
if respond_to?(method_name)
|
18
|
+
dispatcher.public_send(method_name, *arguments, **keyword_arguments, &block)
|
19
|
+
else
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def respond_to_missing?(method_name, _include_private)
|
25
|
+
dispatcher.respond_to?(method_name)
|
18
26
|
end
|
19
27
|
|
20
28
|
private
|
29
|
+
|
21
30
|
attr_reader :instrumentation, :dispatcher
|
22
31
|
end
|
23
32
|
end
|
@@ -25,14 +25,6 @@ module RubyEventStore
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def has_event?(event_id)
|
29
|
-
repository.has_event?(event_id)
|
30
|
-
end
|
31
|
-
|
32
|
-
def last_stream_event(stream)
|
33
|
-
repository.last_stream_event(stream)
|
34
|
-
end
|
35
|
-
|
36
28
|
def read(specification)
|
37
29
|
instrumentation.instrument("read.repository.rails_event_store", specification: specification) do
|
38
30
|
repository.read(specification)
|
@@ -57,7 +49,20 @@ module RubyEventStore
|
|
57
49
|
end
|
58
50
|
end
|
59
51
|
|
52
|
+
def method_missing(method_name, *arguments, **keyword_arguments, &block)
|
53
|
+
if respond_to?(method_name)
|
54
|
+
repository.public_send(method_name, *arguments, **keyword_arguments, &block)
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def respond_to_missing?(method_name, _include_private)
|
61
|
+
repository.respond_to?(method_name)
|
62
|
+
end
|
63
|
+
|
60
64
|
private
|
65
|
+
|
61
66
|
attr_reader :repository, :instrumentation
|
62
67
|
end
|
63
68
|
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module RubyEventStore
|
4
4
|
class LinkByMetadata
|
5
|
-
|
6
5
|
def initialize(event_store:, key:, prefix: nil)
|
7
6
|
@event_store = event_store
|
8
7
|
@key = key
|
@@ -12,31 +11,19 @@ module RubyEventStore
|
|
12
11
|
def call(event)
|
13
12
|
return unless event.metadata.has_key?(@key)
|
14
13
|
|
15
|
-
@event_store.link(
|
16
|
-
[event.event_id],
|
17
|
-
stream_name: "#{@prefix}#{event.metadata.fetch(@key)}"
|
18
|
-
)
|
14
|
+
@event_store.link([event.event_id], stream_name: "#{@prefix}#{event.metadata.fetch(@key)}")
|
19
15
|
end
|
20
|
-
|
21
16
|
end
|
22
17
|
|
23
18
|
class LinkByCorrelationId < LinkByMetadata
|
24
19
|
def initialize(event_store:, prefix: nil)
|
25
|
-
super(
|
26
|
-
event_store: event_store,
|
27
|
-
prefix: prefix,
|
28
|
-
key: :correlation_id,
|
29
|
-
)
|
20
|
+
super(event_store: event_store, prefix: prefix, key: :correlation_id)
|
30
21
|
end
|
31
22
|
end
|
32
23
|
|
33
24
|
class LinkByCausationId < LinkByMetadata
|
34
25
|
def initialize(event_store:, prefix: nil)
|
35
|
-
super(
|
36
|
-
event_store: event_store,
|
37
|
-
prefix: prefix,
|
38
|
-
key: :causation_id,
|
39
|
-
)
|
26
|
+
super(event_store: event_store, prefix: prefix, key: :causation_id)
|
40
27
|
end
|
41
28
|
end
|
42
29
|
|
@@ -47,11 +34,7 @@ module RubyEventStore
|
|
47
34
|
end
|
48
35
|
|
49
36
|
def call(event)
|
50
|
-
@event_store.link(
|
51
|
-
[event.event_id],
|
52
|
-
stream_name: "#{@prefix}#{event.event_type}"
|
53
|
-
)
|
37
|
+
@event_store.link([event.event_id], stream_name: "#{@prefix}#{event.event_type}")
|
54
38
|
end
|
55
39
|
end
|
56
|
-
|
57
40
|
end
|
@@ -4,10 +4,12 @@ module RubyEventStore
|
|
4
4
|
module Mappers
|
5
5
|
class Default < PipelineMapper
|
6
6
|
def initialize(events_class_remapping: {})
|
7
|
-
super(
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
super(
|
8
|
+
Pipeline.new(
|
9
|
+
Transformation::EventClassRemapper.new(events_class_remapping),
|
10
|
+
Transformation::SymbolizeMetadataKeys.new
|
11
|
+
)
|
12
|
+
)
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
@@ -5,31 +5,22 @@ module RubyEventStore
|
|
5
5
|
class EncryptionKey
|
6
6
|
def initialize(cipher:, key:)
|
7
7
|
@cipher = cipher
|
8
|
-
@key
|
8
|
+
@key = key
|
9
9
|
end
|
10
10
|
|
11
11
|
def encrypt(message, iv)
|
12
|
-
crypto
|
13
|
-
crypto.iv
|
12
|
+
crypto = prepare_encrypt(cipher)
|
13
|
+
crypto.iv = iv
|
14
14
|
crypto.key = key
|
15
15
|
|
16
|
-
|
17
|
-
encrypt_authenticated(crypto, message)
|
18
|
-
else
|
19
|
-
crypto.update(message) + crypto.final
|
20
|
-
end
|
16
|
+
crypto.authenticated? ? encrypt_authenticated(crypto, message) : crypto.update(message) + crypto.final
|
21
17
|
end
|
22
18
|
|
23
19
|
def decrypt(message, iv)
|
24
|
-
crypto
|
25
|
-
crypto.iv
|
20
|
+
crypto = prepare_decrypt(cipher)
|
21
|
+
crypto.iv = iv
|
26
22
|
crypto.key = key
|
27
|
-
ciphertext =
|
28
|
-
if crypto.authenticated?
|
29
|
-
ciphertext_from_authenticated(crypto, message)
|
30
|
-
else
|
31
|
-
message
|
32
|
-
end
|
23
|
+
ciphertext = crypto.authenticated? ? ciphertext_from_authenticated(crypto, message) : message
|
33
24
|
(crypto.update(ciphertext) + crypto.final).force_encoding("UTF-8")
|
34
25
|
end
|
35
26
|
|
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'yaml'
|
4
|
-
|
5
3
|
module RubyEventStore
|
6
4
|
module Mappers
|
7
5
|
class EncryptionMapper < PipelineMapper
|
8
|
-
def initialize(key_repository, serializer: YAML, forgotten_data: ForgottenData.new)
|
9
|
-
super(
|
10
|
-
|
11
|
-
|
6
|
+
def initialize(key_repository, serializer: Serializers::YAML, forgotten_data: ForgottenData.new)
|
7
|
+
super(
|
8
|
+
Pipeline.new(
|
9
|
+
Transformation::Encryption.new(key_repository, serializer: serializer, forgotten_data: forgotten_data)
|
10
|
+
)
|
11
|
+
)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -4,22 +4,15 @@ module RubyEventStore
|
|
4
4
|
module Mappers
|
5
5
|
class Pipeline
|
6
6
|
def initialize(*transformations, to_domain_event: Transformation::DomainEvent.new)
|
7
|
-
@transformations = [
|
8
|
-
to_domain_event,
|
9
|
-
transformations,
|
10
|
-
].flatten.freeze
|
7
|
+
@transformations = [to_domain_event, transformations].flatten.freeze
|
11
8
|
end
|
12
9
|
|
13
10
|
def dump(domain_event)
|
14
|
-
transformations.reduce(domain_event)
|
15
|
-
transform.dump(item)
|
16
|
-
end
|
11
|
+
transformations.reduce(domain_event) { |item, transform| transform.dump(item) }
|
17
12
|
end
|
18
13
|
|
19
14
|
def load(record)
|
20
|
-
transformations.reverse.reduce(record)
|
21
|
-
transform.load(item)
|
22
|
-
end
|
15
|
+
transformations.reverse.reduce(record) { |item, transform| transform.load(item) }
|
23
16
|
end
|
24
17
|
|
25
18
|
attr_reader :transformations
|
@@ -5,27 +5,37 @@ module RubyEventStore
|
|
5
5
|
module Transformation
|
6
6
|
class DomainEvent
|
7
7
|
def dump(domain_event)
|
8
|
-
metadata
|
8
|
+
metadata = domain_event.metadata.dup.to_h
|
9
9
|
timestamp = metadata.delete(:timestamp)
|
10
|
-
valid_at
|
10
|
+
valid_at = metadata.delete(:valid_at)
|
11
11
|
Record.new(
|
12
|
-
event_id:
|
13
|
-
metadata:
|
14
|
-
data:
|
12
|
+
event_id: domain_event.event_id,
|
13
|
+
metadata: metadata,
|
14
|
+
data: domain_event.data,
|
15
15
|
event_type: domain_event.event_type,
|
16
|
-
timestamp:
|
17
|
-
valid_at:
|
16
|
+
timestamp: timestamp,
|
17
|
+
valid_at: valid_at
|
18
18
|
)
|
19
19
|
end
|
20
20
|
|
21
21
|
def load(record)
|
22
|
-
Object
|
22
|
+
Object
|
23
|
+
.const_get(record.event_type)
|
24
|
+
.new(
|
25
|
+
event_id: record.event_id,
|
26
|
+
data: record.data,
|
27
|
+
metadata: record.metadata.merge(timestamp: record.timestamp, valid_at: record.valid_at)
|
28
|
+
)
|
29
|
+
rescue NameError
|
30
|
+
Event.new(
|
23
31
|
event_id: record.event_id,
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
data: record.data,
|
33
|
+
metadata:
|
34
|
+
record.metadata.merge(
|
35
|
+
timestamp: record.timestamp,
|
36
|
+
valid_at: record.valid_at,
|
37
|
+
event_type: record.event_type
|
38
|
+
)
|
29
39
|
)
|
30
40
|
end
|
31
41
|
end
|
@@ -6,38 +6,38 @@ module RubyEventStore
|
|
6
6
|
class Encryption
|
7
7
|
class Leaf
|
8
8
|
def self.===(hash)
|
9
|
-
hash.keys.sort.eql? %i
|
9
|
+
hash.keys.sort.eql? %i[cipher identifier iv]
|
10
10
|
end
|
11
11
|
end
|
12
12
|
private_constant :Leaf
|
13
13
|
|
14
14
|
class MissingEncryptionKey < StandardError
|
15
15
|
def initialize(key_identifier)
|
16
|
-
super
|
16
|
+
super "Could not find encryption key for '#{key_identifier}'"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def initialize(key_repository, serializer: YAML, forgotten_data: ForgottenData.new)
|
20
|
+
def initialize(key_repository, serializer: Serializers::YAML, forgotten_data: ForgottenData.new)
|
21
21
|
@key_repository = key_repository
|
22
22
|
@serializer = serializer
|
23
23
|
@forgotten_data = forgotten_data
|
24
24
|
end
|
25
25
|
|
26
26
|
def dump(record)
|
27
|
-
data
|
28
|
-
metadata
|
27
|
+
data = record.data
|
28
|
+
metadata = record.metadata.dup
|
29
29
|
event_class = Object.const_get(record.event_type)
|
30
30
|
|
31
|
-
crypto_description
|
31
|
+
crypto_description = encryption_metadata(data, encryption_schema(event_class))
|
32
32
|
metadata[:encryption] = crypto_description unless crypto_description.empty?
|
33
33
|
|
34
34
|
Record.new(
|
35
|
-
event_id:
|
35
|
+
event_id: record.event_id,
|
36
36
|
event_type: record.event_type,
|
37
|
-
data:
|
38
|
-
metadata:
|
39
|
-
timestamp:
|
40
|
-
valid_at:
|
37
|
+
data: encrypt_data(deep_dup(data), crypto_description),
|
38
|
+
metadata: metadata,
|
39
|
+
timestamp: record.timestamp,
|
40
|
+
valid_at: record.valid_at
|
41
41
|
)
|
42
42
|
end
|
43
43
|
|
@@ -46,16 +46,17 @@ module RubyEventStore
|
|
46
46
|
crypto_description = Hash(metadata.delete(:encryption))
|
47
47
|
|
48
48
|
Record.new(
|
49
|
-
event_id:
|
49
|
+
event_id: record.event_id,
|
50
50
|
event_type: record.event_type,
|
51
|
-
data:
|
52
|
-
metadata:
|
53
|
-
timestamp:
|
54
|
-
valid_at:
|
51
|
+
data: decrypt_data(record.data, crypto_description),
|
52
|
+
metadata: metadata,
|
53
|
+
timestamp: record.timestamp,
|
54
|
+
valid_at: record.valid_at
|
55
55
|
)
|
56
56
|
end
|
57
57
|
|
58
58
|
private
|
59
|
+
|
59
60
|
attr_reader :key_repository, :serializer, :forgotten_data
|
60
61
|
|
61
62
|
def encryption_schema(event_class)
|
@@ -64,9 +65,7 @@ module RubyEventStore
|
|
64
65
|
|
65
66
|
def deep_dup(hash)
|
66
67
|
duplicate = hash.dup
|
67
|
-
duplicate.each
|
68
|
-
duplicate[k] = v.instance_of?(Hash) ? deep_dup(v) : v
|
69
|
-
end
|
68
|
+
duplicate.each { |k, v| duplicate[k] = v.instance_of?(Hash) ? deep_dup(v) : v }
|
70
69
|
duplicate
|
71
70
|
end
|
72
71
|
|
@@ -79,11 +78,7 @@ module RubyEventStore
|
|
79
78
|
key_identifier = value.call(data)
|
80
79
|
encryption_key = key_repository.key_of(key_identifier)
|
81
80
|
raise MissingEncryptionKey.new(key_identifier) unless encryption_key
|
82
|
-
acc[key] = {
|
83
|
-
cipher: encryption_key.cipher,
|
84
|
-
iv: encryption_key.random_iv,
|
85
|
-
identifier: key_identifier,
|
86
|
-
}
|
81
|
+
acc[key] = { cipher: encryption_key.cipher, iv: encryption_key.random_iv, identifier: key_identifier }
|
87
82
|
end
|
88
83
|
acc
|
89
84
|
end
|
@@ -122,7 +117,8 @@ module RubyEventStore
|
|
122
117
|
cryptogram = data.fetch(attribute)
|
123
118
|
return unless cryptogram
|
124
119
|
|
125
|
-
encryption_key = key_repository.key_of(meta.fetch(:identifier), cipher: meta.fetch(:cipher)) or
|
120
|
+
encryption_key = key_repository.key_of(meta.fetch(:identifier), cipher: meta.fetch(:cipher)) or
|
121
|
+
return forgotten_data
|
126
122
|
serializer.load(encryption_key.decrypt(cryptogram, meta.fetch(:iv)))
|
127
123
|
when Hash
|
128
124
|
decrypt_data(data.fetch(attribute), meta)
|
@@ -14,16 +14,17 @@ module RubyEventStore
|
|
14
14
|
|
15
15
|
def load(record)
|
16
16
|
Record.new(
|
17
|
-
event_id:
|
17
|
+
event_id: record.event_id,
|
18
18
|
event_type: class_map[record.event_type] || record.event_type,
|
19
|
-
data:
|
20
|
-
metadata:
|
21
|
-
timestamp:
|
22
|
-
valid_at:
|
19
|
+
data: record.data,
|
20
|
+
metadata: record.metadata,
|
21
|
+
timestamp: record.timestamp,
|
22
|
+
valid_at: record.valid_at
|
23
23
|
)
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
27
|
+
|
27
28
|
attr_reader :class_map
|
28
29
|
end
|
29
30
|
end
|
@@ -13,14 +13,15 @@ module RubyEventStore
|
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
16
|
+
|
16
17
|
def stringify(record)
|
17
18
|
Record.new(
|
18
|
-
event_id:
|
19
|
+
event_id: record.event_id,
|
19
20
|
event_type: record.event_type,
|
20
|
-
data:
|
21
|
-
metadata:
|
22
|
-
timestamp:
|
23
|
-
valid_at:
|
21
|
+
data: record.data,
|
22
|
+
metadata: TransformKeys.stringify(record.metadata),
|
23
|
+
timestamp: record.timestamp,
|
24
|
+
valid_at: record.valid_at
|
24
25
|
)
|
25
26
|
end
|
26
27
|
end
|
@@ -13,14 +13,15 @@ module RubyEventStore
|
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
16
|
+
|
16
17
|
def symbolize(record)
|
17
18
|
Record.new(
|
18
|
-
event_id:
|
19
|
+
event_id: record.event_id,
|
19
20
|
event_type: record.event_type,
|
20
|
-
data:
|
21
|
-
metadata:
|
22
|
-
timestamp:
|
23
|
-
valid_at:
|
21
|
+
data: record.data,
|
22
|
+
metadata: TransformKeys.symbolize(record.metadata),
|
23
|
+
timestamp: record.timestamp,
|
24
|
+
valid_at: record.valid_at
|
24
25
|
)
|
25
26
|
end
|
26
27
|
end
|
@@ -10,13 +10,9 @@ module RubyEventStore
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def call(record)
|
13
|
-
identity
|
13
|
+
identity = lambda { |r| r }
|
14
14
|
new_record = @upcast_map.fetch(record.event_type, identity)[record]
|
15
|
-
|
16
|
-
record
|
17
|
-
else
|
18
|
-
call(new_record)
|
19
|
-
end
|
15
|
+
new_record.equal?(record) ? record : call(new_record)
|
20
16
|
end
|
21
17
|
end
|
22
18
|
|
@@ -1,19 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "date"
|
4
|
+
require "time"
|
5
|
+
require "forwardable"
|
6
6
|
|
7
7
|
module RubyEventStore
|
8
8
|
class Metadata
|
9
9
|
include Enumerable
|
10
|
-
extend
|
10
|
+
extend Forwardable
|
11
11
|
|
12
12
|
def initialize(h = self)
|
13
13
|
@h = {}
|
14
|
-
h.each
|
15
|
-
self[k] = (v)
|
16
|
-
end
|
14
|
+
h.each { |k, v| self[k] = (v) }
|
17
15
|
end
|
18
16
|
|
19
17
|
def [](key)
|
@@ -22,23 +20,54 @@ module RubyEventStore
|
|
22
20
|
end
|
23
21
|
|
24
22
|
def []=(key, val)
|
25
|
-
raise ArgumentError unless allowed_types.any?{|klass| klass === val }
|
23
|
+
raise ArgumentError unless allowed_types.any? { |klass| klass === val }
|
26
24
|
raise ArgumentError unless Symbol === key
|
27
|
-
@h[key]=val
|
25
|
+
@h[key] = val
|
28
26
|
end
|
29
27
|
|
30
28
|
def each(&block)
|
31
29
|
@h.each(&block)
|
32
30
|
end
|
33
31
|
|
34
|
-
SAFE_HASH_METHODS = [
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
32
|
+
SAFE_HASH_METHODS = %i[
|
33
|
+
<
|
34
|
+
<=
|
35
|
+
>
|
36
|
+
>=
|
37
|
+
assoc
|
38
|
+
clear
|
39
|
+
compact
|
40
|
+
compact!
|
41
|
+
delete
|
42
|
+
delete_if
|
43
|
+
dig
|
44
|
+
each_key
|
45
|
+
each_pair
|
46
|
+
each_value
|
47
|
+
empty?
|
48
|
+
fetch
|
49
|
+
fetch_values
|
50
|
+
flatten
|
51
|
+
has_key?
|
52
|
+
has_value?
|
53
|
+
keep_if
|
54
|
+
key
|
55
|
+
key?
|
56
|
+
keys
|
57
|
+
length
|
58
|
+
rassoc
|
59
|
+
reject!
|
60
|
+
select!
|
61
|
+
shift
|
62
|
+
size
|
63
|
+
slice
|
64
|
+
to_proc
|
65
|
+
transform_keys
|
66
|
+
transform_values
|
67
|
+
value?
|
68
|
+
values
|
69
|
+
values_at
|
70
|
+
]
|
42
71
|
|
43
72
|
delegate SAFE_HASH_METHODS => :@h
|
44
73
|
|
@@ -15,9 +15,9 @@ module RubyEventStore
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def initialize(streams: [])
|
18
|
-
@streams
|
18
|
+
@streams = streams
|
19
19
|
@handlers = {}
|
20
|
-
@init
|
20
|
+
@init = -> { {} }
|
21
21
|
end
|
22
22
|
|
23
23
|
attr_reader :streams, :handlers
|
@@ -28,9 +28,7 @@ module RubyEventStore
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def when(events, handler)
|
31
|
-
Array(events).each
|
32
|
-
handlers[event.to_s] = handler
|
33
|
-
end
|
31
|
+
Array(events).each { |event| handlers[event.to_s] = handler }
|
34
32
|
|
35
33
|
self
|
36
34
|
end
|
@@ -53,33 +51,27 @@ module RubyEventStore
|
|
53
51
|
|
54
52
|
def run(event_store, start: nil, count: PAGE_SIZE)
|
55
53
|
return initial_state if handled_events.empty?
|
56
|
-
|
57
|
-
reduce_from_streams(event_store, start, count)
|
58
|
-
else
|
59
|
-
reduce_from_all_streams(event_store, start, count)
|
60
|
-
end
|
54
|
+
streams.any? ? reduce_from_streams(event_store, start, count) : reduce_from_all_streams(event_store, start, count)
|
61
55
|
end
|
62
56
|
|
63
57
|
private
|
64
58
|
|
65
59
|
def valid_starting_point?(start)
|
66
60
|
return true unless start
|
67
|
-
|
68
|
-
(start.instance_of?(Array) && start.size === streams.size)
|
69
|
-
else
|
70
|
-
start.instance_of?(String)
|
71
|
-
end
|
61
|
+
streams.any? ? (start.instance_of?(Array) && start.size === streams.size) : start.instance_of?(String)
|
72
62
|
end
|
73
63
|
|
74
64
|
def reduce_from_streams(event_store, start, count)
|
75
|
-
raise ArgumentError.new(
|
76
|
-
streams
|
77
|
-
|
78
|
-
|
65
|
+
raise ArgumentError.new("Start must be an array with event ids") unless valid_starting_point?(start)
|
66
|
+
streams
|
67
|
+
.zip(start_events(start))
|
68
|
+
.reduce(initial_state) do |state, (stream_name, start_event_id)|
|
69
|
+
read_scope(event_store, stream_name, count, start_event_id).reduce(state, &method(:transition))
|
70
|
+
end
|
79
71
|
end
|
80
72
|
|
81
73
|
def reduce_from_all_streams(event_store, start, count)
|
82
|
-
raise ArgumentError.new(
|
74
|
+
raise ArgumentError.new("Start must be valid event id") unless valid_starting_point?(start)
|
83
75
|
read_scope(event_store, nil, count, start).reduce(initial_state, &method(:transition))
|
84
76
|
end
|
85
77
|
|