ruby_event_store 2.17.1 → 2.19.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.
@@ -2,50 +2,70 @@
2
2
 
3
3
  module RubyEventStore
4
4
  class InstrumentedRepository
5
+ DEPRECATION_MESSAGE = <<~EOW
6
+ Instrumentation event names *.rails_event_store are deprecated and will be removed in the next major release.
7
+ Use *.ruby_event_store instead.
8
+ EOW
9
+ private_constant :DEPRECATION_MESSAGE
10
+
5
11
  def initialize(repository, instrumentation)
6
12
  @repository = repository
7
13
  @instrumentation = instrumentation
8
14
  end
9
15
 
10
16
  def append_to_stream(records, stream, expected_version)
11
- instrumentation.instrument("append_to_stream.repository.rails_event_store", events: records, stream: stream) do
12
- repository.append_to_stream(records, stream, expected_version)
17
+ instrumentation.instrument("append_to_stream.repository.ruby_event_store", records: records, events: records, stream: stream) do
18
+ deprecated_instrument("append_to_stream.repository.rails_event_store", { records: records, events: records, stream: stream }) do
19
+ repository.append_to_stream(records, stream, expected_version)
20
+ end
13
21
  end
14
22
  end
15
23
 
16
24
  def link_to_stream(event_ids, stream, expected_version)
17
- instrumentation.instrument("link_to_stream.repository.rails_event_store", event_ids: event_ids, stream: stream) do
18
- repository.link_to_stream(event_ids, stream, expected_version)
25
+ instrumentation.instrument("link_to_stream.repository.ruby_event_store", event_ids: event_ids, stream: stream) do
26
+ deprecated_instrument("link_to_stream.repository.rails_event_store", event_ids: event_ids, stream: stream) do
27
+ repository.link_to_stream(event_ids, stream, expected_version)
28
+ end
19
29
  end
20
30
  end
21
31
 
22
32
  def delete_stream(stream)
23
- instrumentation.instrument("delete_stream.repository.rails_event_store", stream: stream) do
24
- repository.delete_stream(stream)
33
+ instrumentation.instrument("delete_stream.repository.ruby_event_store", stream: stream) do
34
+ deprecated_instrument("delete_stream.repository.rails_event_store", stream: stream) do
35
+ repository.delete_stream(stream)
36
+ end
25
37
  end
26
38
  end
27
39
 
28
40
  def read(specification)
29
- instrumentation.instrument("read.repository.rails_event_store", specification: specification) do
30
- repository.read(specification)
41
+ instrumentation.instrument("read.repository.ruby_event_store", specification: specification) do
42
+ deprecated_instrument("read.repository.rails_event_store", specification: specification) do
43
+ repository.read(specification)
44
+ end
31
45
  end
32
46
  end
33
47
 
34
48
  def count(specification)
35
- instrumentation.instrument("count.repository.rails_event_store", specification: specification) do
36
- repository.count(specification)
49
+ instrumentation.instrument("count.repository.ruby_event_store", specification: specification) do
50
+ deprecated_instrument("count.repository.rails_event_store", specification: specification) do
51
+ repository.count(specification)
52
+ end
37
53
  end
38
54
  end
39
55
 
40
- def update_messages(messages)
41
- instrumentation.instrument("update_messages.repository.rails_event_store", messages: messages) do
42
- repository.update_messages(messages)
56
+ def update_messages(records)
57
+ instrumentation.instrument("update_messages.repository.ruby_event_store", records: records, messages: records) do
58
+ deprecated_instrument("update_messages.repository.rails_event_store", { records: records, messages: records }) do
59
+ repository.update_messages(records)
60
+ end
43
61
  end
44
62
  end
45
63
 
46
64
  def streams_of(event_id)
47
- instrumentation.instrument("streams_of.repository.rails_event_store", event_id: event_id) do
48
- repository.streams_of(event_id)
65
+ instrumentation.instrument("streams_of.repository.ruby_event_store", event_id: event_id) do
66
+ deprecated_instrument("streams_of.repository.rails_event_store", event_id: event_id) do
67
+ repository.streams_of(event_id)
68
+ end
49
69
  end
50
70
  end
51
71
 
@@ -64,5 +84,17 @@ module RubyEventStore
64
84
  private
65
85
 
66
86
  attr_reader :repository, :instrumentation
87
+
88
+ def deprecated_instrument(name, payload, &block)
89
+ canonical_name = name.sub("rails_event_store", "ruby_event_store")
90
+ old_listeners = instrumentation.notifier.all_listeners_for(name)
91
+ new_listeners = instrumentation.notifier.all_listeners_for(canonical_name)
92
+ if (old_listeners - new_listeners).any?
93
+ warn DEPRECATION_MESSAGE
94
+ instrumentation.instrument(name, payload, &block)
95
+ else
96
+ yield
97
+ end
98
+ end
67
99
  end
68
100
  end
@@ -4,12 +4,20 @@ module RubyEventStore
4
4
  module Mappers
5
5
  class Default < PipelineMapper
6
6
  def initialize(events_class_remapping: {})
7
- super(
8
- Pipeline.new(
9
- Transformation::EventClassRemapper.new(events_class_remapping),
10
- Transformation::SymbolizeMetadataKeys.new,
11
- ),
12
- )
7
+ if events_class_remapping.any?
8
+ warn <<~EOW
9
+ DEPRECATION WARNING: `events_class_remapping` option in `RubyEventStore::Mappers::Default` is deprecated and will be removed in the next major release.
10
+ Use `RubyEventStore::Mappers::Transformation::Upcast` instead.
11
+ EOW
12
+ super(
13
+ Pipeline.new(
14
+ Transformation::EventClassRemapper.new(events_class_remapping),
15
+ Transformation::SymbolizeMetadataKeys.new,
16
+ ),
17
+ )
18
+ else
19
+ super(Pipeline.new(Transformation::SymbolizeMetadataKeys.new))
20
+ end
13
21
  end
14
22
  end
15
23
  end
@@ -3,26 +3,48 @@
3
3
  module RubyEventStore
4
4
  module Mappers
5
5
  class InstrumentedBatchMapper
6
+ DEPRECATION_MESSAGE = <<~EOW
7
+ Instrumentation event names *.rails_event_store are deprecated and will be removed in the next major release.
8
+ Use *.ruby_event_store instead.
9
+ EOW
10
+ private_constant :DEPRECATION_MESSAGE
11
+
6
12
  def initialize(mapper, instrumentation)
7
13
  @mapper = mapper
8
14
  @instrumentation = instrumentation
9
15
  end
10
16
 
11
17
  def events_to_records(events)
12
- instrumentation.instrument("events_to_records.mapper.rails_event_store", domain_events: events) do
13
- mapper.events_to_records(events)
18
+ instrumentation.instrument("events_to_records.mapper.ruby_event_store", domain_events: events) do
19
+ deprecated_instrument("events_to_records.mapper.rails_event_store", domain_events: events) do
20
+ mapper.events_to_records(events)
21
+ end
14
22
  end
15
23
  end
16
24
 
17
25
  def records_to_events(records)
18
- instrumentation.instrument("records_to_events.mapper.rails_event_store", records: records) do
19
- mapper.records_to_events(records)
26
+ instrumentation.instrument("records_to_events.mapper.ruby_event_store", records: records) do
27
+ deprecated_instrument("records_to_events.mapper.rails_event_store", records: records) do
28
+ mapper.records_to_events(records)
29
+ end
20
30
  end
21
31
  end
22
32
 
23
33
  private
24
34
 
25
35
  attr_reader :instrumentation, :mapper
36
+
37
+ def deprecated_instrument(name, payload, &block)
38
+ canonical_name = name.sub("rails_event_store", "ruby_event_store")
39
+ old_listeners = instrumentation.notifier.all_listeners_for(name)
40
+ new_listeners = instrumentation.notifier.all_listeners_for(canonical_name)
41
+ if (old_listeners - new_listeners).any?
42
+ warn DEPRECATION_MESSAGE
43
+ instrumentation.instrument(name, payload, &block)
44
+ else
45
+ yield
46
+ end
47
+ end
26
48
  end
27
49
  end
28
50
  end
@@ -3,26 +3,63 @@
3
3
  module RubyEventStore
4
4
  module Mappers
5
5
  class InstrumentedMapper
6
+ DEPRECATION_MESSAGE = <<~EOW
7
+ Instrumentation event names *.rails_event_store are deprecated and will be removed in the next major release.
8
+ Use *.ruby_event_store instead.
9
+ EOW
10
+ private_constant :DEPRECATION_MESSAGE
11
+
12
+ RENAME_DEPRECATION_MESSAGE = <<~EOW
13
+ Instrumentation event names serialize.mapper.ruby_event_store and deserialize.mapper.ruby_event_store are deprecated and will be removed in the next major release.
14
+ Use event_to_record.mapper.ruby_event_store and record_to_event.mapper.ruby_event_store instead.
15
+ The domain_event: payload key in serialize.mapper.ruby_event_store has been renamed to event: in event_to_record.mapper.ruby_event_store.
16
+ EOW
17
+ private_constant :RENAME_DEPRECATION_MESSAGE
18
+
6
19
  def initialize(mapper, instrumentation)
7
20
  @mapper = mapper
8
21
  @instrumentation = instrumentation
9
22
  end
10
23
 
11
24
  def event_to_record(event)
12
- instrumentation.instrument("serialize.mapper.rails_event_store", domain_event: event) do
13
- mapper.event_to_record(event)
25
+ instrumentation.instrument("event_to_record.mapper.ruby_event_store", event: event) do
26
+ deprecated_instrument("serialize.mapper.ruby_event_store", { domain_event: event },
27
+ canonical: "event_to_record.mapper.ruby_event_store",
28
+ message: RENAME_DEPRECATION_MESSAGE) do
29
+ deprecated_instrument("serialize.mapper.rails_event_store", { domain_event: event }) do
30
+ mapper.event_to_record(event)
31
+ end
32
+ end
14
33
  end
15
34
  end
16
35
 
17
36
  def record_to_event(record)
18
- instrumentation.instrument("deserialize.mapper.rails_event_store", record: record) do
19
- mapper.record_to_event(record)
37
+ instrumentation.instrument("record_to_event.mapper.ruby_event_store", record: record) do
38
+ deprecated_instrument("deserialize.mapper.ruby_event_store", { record: record },
39
+ canonical: "record_to_event.mapper.ruby_event_store",
40
+ message: RENAME_DEPRECATION_MESSAGE) do
41
+ deprecated_instrument("deserialize.mapper.rails_event_store", { record: record }) do
42
+ mapper.record_to_event(record)
43
+ end
44
+ end
20
45
  end
21
46
  end
22
47
 
23
48
  private
24
49
 
25
50
  attr_reader :instrumentation, :mapper
51
+
52
+ def deprecated_instrument(name, payload, canonical: nil, message: DEPRECATION_MESSAGE, &block)
53
+ canonical_name = canonical || name.sub("rails_event_store", "ruby_event_store")
54
+ old_listeners = instrumentation.notifier.all_listeners_for(name)
55
+ new_listeners = instrumentation.notifier.all_listeners_for(canonical_name)
56
+ if (old_listeners - new_listeners).any?
57
+ warn message
58
+ instrumentation.instrument(name, payload, &block)
59
+ else
60
+ yield
61
+ end
62
+ end
26
63
  end
27
64
  end
28
65
  end
@@ -4,6 +4,10 @@ module RubyEventStore
4
4
  module Mappers
5
5
  class NullMapper < PipelineMapper
6
6
  def initialize
7
+ warn <<~EOW
8
+ DEPRECATION WARNING: `RubyEventStore::Mappers::NullMapper` is deprecated and will be removed in the next major release.
9
+ Use `RubyEventStore::Mappers::Default.new` instead.
10
+ EOW
7
11
  super(Pipeline.new)
8
12
  end
9
13
  end
@@ -5,6 +5,10 @@ module RubyEventStore
5
5
  module Transformation
6
6
  class EventClassRemapper
7
7
  def initialize(class_map)
8
+ warn <<~EOW
9
+ DEPRECATION WARNING: `RubyEventStore::Mappers::Transformation::EventClassRemapper` is deprecated and will be removed in the next major release.
10
+ Use `RubyEventStore::Mappers::Transformation::Upcast` instead.
11
+ EOW
8
12
  @class_map = class_map
9
13
  end
10
14
 
@@ -2,94 +2,126 @@
2
2
 
3
3
  module RubyEventStore
4
4
  class Projection
5
- private_class_method :new
6
-
7
- def self.from_stream(stream_or_streams)
8
- streams = Array(stream_or_streams)
9
- raise(ArgumentError, "At least one stream must be given") if streams.empty?
10
- new(streams: streams)
5
+ ANONYMOUS_CLASS = "#<Class:".freeze
6
+ DEPRECATION_MESSAGE = <<~EOW
7
+ RubyEventStore::Projection from_stream/from_all_streams/init/when/run API is deprecated and will be removed in the next major release.
8
+ Use Projection.init(initial_state).on(EventClass) { |state, event| new_state }.call(scope) instead.
9
+ EOW
10
+ MULTI_SCOPE_DEPRECATION_MESSAGE = <<~EOW
11
+ Passing multiple scopes to RubyEventStore::Projection#call is deprecated and will be removed in the next major release.
12
+ Use a single scope instead, e.g. call(event_store.read.stream("stream_name")).
13
+ EOW
14
+ NEW_CONSTRUCTOR_DEPRECATION_MESSAGE = <<~EOW
15
+ RubyEventStore::Projection.new is deprecated and will be removed in the next major release.
16
+ Use Projection.init(initial_state) instead.
17
+ EOW
18
+ private_constant :ANONYMOUS_CLASS, :DEPRECATION_MESSAGE, :MULTI_SCOPE_DEPRECATION_MESSAGE, :NEW_CONSTRUCTOR_DEPRECATION_MESSAGE
19
+
20
+ def initialize(initial_state = nil, _internal: false)
21
+ warn NEW_CONSTRUCTOR_DEPRECATION_MESSAGE unless _internal
22
+ @handlers = {}
23
+ @init = -> { initial_state }
24
+ @streams = []
11
25
  end
12
26
 
13
- def self.from_all_streams
14
- new
27
+ def self.init(initial_state = nil)
28
+ new(initial_state, _internal: true)
15
29
  end
16
30
 
17
- def initialize(streams: [])
18
- @streams = streams
19
- @handlers = {}
20
- @init = -> { {} }
21
- end
31
+ def on(*event_klasses, &block)
32
+ raise(ArgumentError, "No handler block given") unless block_given?
22
33
 
23
- attr_reader :streams, :handlers
34
+ event_klasses.each do |event_klass|
35
+ name = event_klass.to_s
36
+ raise(ArgumentError, "Anonymous class is missing name") if name.start_with? ANONYMOUS_CLASS
24
37
 
25
- def init(handler)
26
- @init = handler
38
+ @handlers[name] = ->(state, event) { block.call(state, event) }
39
+ end
27
40
  self
28
41
  end
29
42
 
30
- def when(events, handler)
31
- Array(events).each { |event| handlers[event.to_s] = handler }
43
+ def call(*scopes)
44
+ return initial_state if handled_events.empty?
32
45
 
33
- self
46
+ warn MULTI_SCOPE_DEPRECATION_MESSAGE if scopes.size > 1
47
+
48
+ scopes.reduce(initial_state) do |state, scope|
49
+ scope.of_type(handled_events).reduce(state, &method(:transition))
50
+ end
34
51
  end
35
52
 
36
- def initial_state
37
- @init.call
53
+ def self.from_stream(stream_or_streams)
54
+ warn DEPRECATION_MESSAGE
55
+ streams = Array(stream_or_streams)
56
+ raise(ArgumentError, "At least one stream must be given") if streams.empty?
57
+ projection = new(_internal: true)
58
+ projection.instance_variable_set(:@streams, streams)
59
+ projection
38
60
  end
39
61
 
40
- def current_state
41
- @current_state ||= initial_state
62
+ def self.from_all_streams
63
+ warn DEPRECATION_MESSAGE
64
+ new(_internal: true)
42
65
  end
43
66
 
44
- def call(event)
45
- handlers.fetch(event.event_type).(current_state, event)
67
+ def init(handler)
68
+ warn DEPRECATION_MESSAGE
69
+ @init = handler
70
+ self
46
71
  end
47
72
 
48
- def handled_events
49
- handlers.keys
73
+ def when(events, handler)
74
+ warn DEPRECATION_MESSAGE
75
+ Array(events).each do |event_klass|
76
+ name = event_klass.to_s
77
+ @handlers[name] = ->(state, event) { handler.call(state, event); state }
78
+ end
79
+ self
50
80
  end
51
81
 
52
82
  def run(event_store, start: nil, count: PAGE_SIZE)
53
- return initial_state if handled_events.empty?
54
- streams.any? ? reduce_from_streams(event_store, start, count) : reduce_from_all_streams(event_store, start, count)
83
+ warn DEPRECATION_MESSAGE
84
+
85
+ if @streams.any?
86
+ raise ArgumentError, "Start must be an array with event ids" unless valid_start_for_streams?(start)
87
+ scopes =
88
+ @streams.zip(start || []).map do |stream, start_event_id|
89
+ scope = event_store.read.stream(stream).in_batches(count)
90
+ scope = scope.from(start_event_id) if start_event_id
91
+ scope
92
+ end
93
+ else
94
+ raise ArgumentError, "Start must be valid event id" unless valid_start_for_all_streams?(start)
95
+ scope = event_store.read.in_batches(count)
96
+ scope = scope.from(start) if start
97
+ scopes = [scope]
98
+ end
99
+
100
+ call(*scopes)
55
101
  end
56
102
 
57
103
  private
58
104
 
59
- def valid_starting_point?(start)
60
- return true unless start
61
- streams.any? ? (start.instance_of?(Array) && start.size === streams.size) : start.instance_of?(String)
62
- end
63
-
64
- def reduce_from_streams(event_store, start, count)
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
105
+ def initial_state
106
+ @init.call
71
107
  end
72
108
 
73
- def reduce_from_all_streams(event_store, start, count)
74
- raise ArgumentError.new("Start must be valid event id") unless valid_starting_point?(start)
75
- read_scope(event_store, nil, count, start).reduce(initial_state, &method(:transition))
109
+ def handled_events
110
+ @handlers.keys
76
111
  end
77
112
 
78
- def read_scope(event_store, stream, count, start)
79
- scope = event_store.read.in_batches(count)
80
- scope = scope.of_type(handled_events)
81
- scope = scope.stream(stream) if stream
82
- scope = scope.from(start) if start
83
- scope
113
+ def transition(state, event)
114
+ @handlers.fetch(event.event_type).call(state, event)
84
115
  end
85
116
 
86
- def start_events(start)
87
- start ? start : Array.new
117
+ def valid_start_for_streams?(start)
118
+ return true unless start
119
+ start.instance_of?(Array) && start.size == @streams.size
88
120
  end
89
121
 
90
- def transition(state, event)
91
- handlers.fetch(event.event_type).call(state, event)
92
- state
122
+ def valid_start_for_all_streams?(start)
123
+ return true unless start
124
+ start.instance_of?(String)
93
125
  end
94
126
  end
95
127
  end