ruby_event_store 1.2.2 → 2.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/README.md +3 -1
- data/lib/ruby_event_store.rb +3 -7
- data/lib/ruby_event_store/broker.rb +3 -3
- data/lib/ruby_event_store/client.rb +47 -23
- data/lib/ruby_event_store/composed_dispatcher.rb +2 -2
- data/lib/ruby_event_store/constants.rb +1 -0
- data/lib/ruby_event_store/errors.rb +0 -1
- data/lib/ruby_event_store/event.rb +8 -1
- data/lib/ruby_event_store/immediate_async_dispatcher.rb +2 -2
- data/lib/ruby_event_store/in_memory_repository.rb +98 -59
- data/lib/ruby_event_store/instrumented_dispatcher.rb +2 -2
- data/lib/ruby_event_store/instrumented_repository.rb +3 -3
- data/lib/ruby_event_store/mappers/default.rb +3 -8
- data/lib/ruby_event_store/mappers/encryption_mapper.rb +3 -4
- data/lib/ruby_event_store/mappers/instrumented_mapper.rb +4 -4
- data/lib/ruby_event_store/mappers/json_mapper.rb +7 -7
- data/lib/ruby_event_store/mappers/pipeline.rb +2 -5
- data/lib/ruby_event_store/mappers/pipeline_mapper.rb +2 -2
- data/lib/ruby_event_store/mappers/transformation/domain_event.rb +16 -8
- data/lib/ruby_event_store/mappers/transformation/encryption.rb +20 -12
- data/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb +11 -4
- data/lib/ruby_event_store/mappers/transformation/stringify_metadata_keys.rb +12 -7
- data/lib/ruby_event_store/mappers/transformation/symbolize_metadata_keys.rb +12 -7
- data/lib/ruby_event_store/mappers/transformation/upcast.rb +37 -0
- data/lib/ruby_event_store/null.rb +13 -0
- data/lib/ruby_event_store/projection.rb +2 -1
- data/lib/ruby_event_store/record.rb +68 -0
- data/lib/ruby_event_store/serialized_record.rb +23 -4
- data/lib/ruby_event_store/spec/broker_lint.rb +9 -9
- data/lib/ruby_event_store/spec/event_repository_lint.rb +267 -105
- data/lib/ruby_event_store/spec/mapper_lint.rb +6 -6
- data/lib/ruby_event_store/spec/subscriptions_lint.rb +25 -0
- data/lib/ruby_event_store/specification.rb +100 -7
- data/lib/ruby_event_store/specification_reader.rb +2 -2
- data/lib/ruby_event_store/specification_result.rb +86 -2
- data/lib/ruby_event_store/subscriptions.rb +23 -9
- data/lib/ruby_event_store/transform_keys.rb +5 -5
- data/lib/ruby_event_store/version.rb +1 -1
- metadata +15 -21
- data/CHANGELOG.md +0 -93
- data/Gemfile +0 -11
- data/Makefile +0 -22
- data/lib/ruby_event_store/mappers/protobuf.rb +0 -24
- data/lib/ruby_event_store/mappers/transformation/item.rb +0 -56
- data/lib/ruby_event_store/mappers/transformation/proto_event.rb +0 -17
- data/lib/ruby_event_store/mappers/transformation/protobuf_encoder.rb +0 -30
- data/lib/ruby_event_store/mappers/transformation/protobuf_nested_struct_metadata.rb +0 -30
- data/lib/ruby_event_store/mappers/transformation/serialization.rb +0 -34
- data/lib/ruby_event_store/mappers/transformation/serialized_record.rb +0 -27
- data/ruby_event_store.gemspec +0 -29
| @@ -1,17 +1,17 @@ | |
| 1 1 | 
             
            module RubyEventStore
         | 
| 2 | 
            -
              RSpec.shared_examples :mapper do |mapper, domain_event|
         | 
| 3 | 
            -
                specify " | 
| 4 | 
            -
                  record = mapper. | 
| 2 | 
            +
              ::RSpec.shared_examples :mapper do |mapper, domain_event|
         | 
| 3 | 
            +
                specify "event_to_record returns instance of Record" do
         | 
| 4 | 
            +
                  record = mapper.event_to_record(domain_event)
         | 
| 5 5 |  | 
| 6 | 
            -
                  expect(record).to            be_kind_of( | 
| 6 | 
            +
                  expect(record).to            be_kind_of(Record)
         | 
| 7 7 | 
             
                  expect(record.event_id).to   eq(domain_event.event_id)
         | 
| 8 8 | 
             
                  expect(record.event_type).to eq(domain_event.event_type)
         | 
| 9 9 | 
             
                end
         | 
| 10 10 |  | 
| 11 11 | 
             
                specify "serialize and deserialize gives equal event" do
         | 
| 12 | 
            -
                  record = mapper. | 
| 12 | 
            +
                  record = mapper.event_to_record(domain_event)
         | 
| 13 13 |  | 
| 14 | 
            -
                  expect(mapper. | 
| 14 | 
            +
                  expect(mapper.record_to_event(record)).to eq(domain_event)
         | 
| 15 15 | 
             
                end
         | 
| 16 16 | 
             
              end
         | 
| 17 17 | 
             
            end
         | 
| @@ -39,10 +39,16 @@ RSpec.shared_examples :subscriptions do |subscriptions_class| | |
| 39 39 | 
             
                subscriptions.add_thread_subscription(handler, [Test1DomainEvent, Test3DomainEvent])
         | 
| 40 40 | 
             
                subscriptions.add_thread_subscription(another_handler, [Test2DomainEvent])
         | 
| 41 41 | 
             
                subscriptions.add_thread_global_subscription(global_handler)
         | 
| 42 | 
            +
                t = Thread.new do
         | 
| 43 | 
            +
                  subscriptions.add_thread_subscription(handler, [Test2DomainEvent])
         | 
| 44 | 
            +
                  subscriptions.add_thread_global_subscription(another_handler)
         | 
| 45 | 
            +
                  expect(subscriptions.all_for('Test2DomainEvent')).to eq([another_handler, handler])
         | 
| 46 | 
            +
                end
         | 
| 42 47 |  | 
| 43 48 | 
             
                expect(subscriptions.all_for('Test1DomainEvent')).to eq([global_handler, handler])
         | 
| 44 49 | 
             
                expect(subscriptions.all_for('Test2DomainEvent')).to eq([global_handler, another_handler])
         | 
| 45 50 | 
             
                expect(subscriptions.all_for('Test3DomainEvent')).to eq([global_handler, handler])
         | 
| 51 | 
            +
                t.join
         | 
| 46 52 | 
             
              end
         | 
| 47 53 |  | 
| 48 54 | 
             
              it 'returns lambda as an output of global subscribe methods' do
         | 
| @@ -108,4 +114,23 @@ RSpec.shared_examples :subscriptions do |subscriptions_class| | |
| 108 114 |  | 
| 109 115 | 
             
                expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler, handler])
         | 
| 110 116 | 
             
              end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
              it 'subscribes by type of event which is a class' do
         | 
| 119 | 
            +
                handler         = TestHandler.new
         | 
| 120 | 
            +
                subscriptions.add_subscription(handler, [Test1DomainEvent])
         | 
| 121 | 
            +
                subscriptions.add_thread_subscription(handler, [Test1DomainEvent])
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler, handler])
         | 
| 124 | 
            +
                expect(subscriptions.all_for(Test1DomainEvent)).to eq([handler, handler])
         | 
| 125 | 
            +
              end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
              it 'subscribes by type of event which is a class or string with custom type resolver' do
         | 
| 128 | 
            +
                subscriptions = subscriptions_class.new(event_type_resolver: ->(type) { type.to_s.reverse })
         | 
| 129 | 
            +
                handler         = TestHandler.new
         | 
| 130 | 
            +
                subscriptions.add_subscription(handler, [Test1DomainEvent])
         | 
| 131 | 
            +
                subscriptions.add_thread_subscription(handler, ['Test1DomainEvent'])
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                expect(subscriptions.all_for('Test1DomainEvent')).to eq([handler, handler])
         | 
| 134 | 
            +
                expect(subscriptions.all_for(Test1DomainEvent)).to eq([handler, handler])
         | 
| 135 | 
            +
              end
         | 
| 111 136 | 
             
            end
         | 
| @@ -35,7 +35,7 @@ module RubyEventStore | |
| 35 35 | 
             
                # Limits the query to events before or after another event.
         | 
| 36 36 | 
             
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 37 37 | 
             
                #
         | 
| 38 | 
            -
                # @param  | 
| 38 | 
            +
                # @param stop [String] id of event to start reading from.
         | 
| 39 39 | 
             
                # @return [Specification]
         | 
| 40 40 | 
             
                def to(stop)
         | 
| 41 41 | 
             
                  raise InvalidPageStop if stop.nil? || stop.empty?
         | 
| @@ -43,6 +43,99 @@ module RubyEventStore | |
| 43 43 | 
             
                  Specification.new(reader, result.dup { |r| r.stop = stop })
         | 
| 44 44 | 
             
                end
         | 
| 45 45 |  | 
| 46 | 
            +
                # Limits the query to events that later than given time.
         | 
| 47 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 48 | 
            +
                #
         | 
| 49 | 
            +
                # @param time [Time]
         | 
| 50 | 
            +
                # @return [Specification]
         | 
| 51 | 
            +
                def older_than(time)
         | 
| 52 | 
            +
                  raise ArgumentError unless time.respond_to?(:to_time)
         | 
| 53 | 
            +
                  Specification.new(
         | 
| 54 | 
            +
                    reader,
         | 
| 55 | 
            +
                    result.dup do |r|
         | 
| 56 | 
            +
                      r.older_than          = time
         | 
| 57 | 
            +
                      r.older_than_or_equal = nil
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                  )
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                # Limits the query to events that occurred on given time or later.
         | 
| 63 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 64 | 
            +
                #
         | 
| 65 | 
            +
                # @param time [Time]
         | 
| 66 | 
            +
                # @return [Specification]
         | 
| 67 | 
            +
                def older_than_or_equal(time)
         | 
| 68 | 
            +
                  raise ArgumentError unless time.respond_to?(:to_time)
         | 
| 69 | 
            +
                  Specification.new(
         | 
| 70 | 
            +
                    reader,
         | 
| 71 | 
            +
                    result.dup do |r|
         | 
| 72 | 
            +
                      r.older_than          = nil
         | 
| 73 | 
            +
                      r.older_than_or_equal = time
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  )
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                # Limits the query to events that occurred earlier than given time.
         | 
| 79 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 80 | 
            +
                #
         | 
| 81 | 
            +
                # @param time [Time]
         | 
| 82 | 
            +
                # @return [Specification]
         | 
| 83 | 
            +
                def newer_than(time)
         | 
| 84 | 
            +
                  raise ArgumentError unless time.respond_to?(:to_time)
         | 
| 85 | 
            +
                  Specification.new(
         | 
| 86 | 
            +
                    reader,
         | 
| 87 | 
            +
                    result.dup do |r|
         | 
| 88 | 
            +
                      r.newer_than_or_equal = nil
         | 
| 89 | 
            +
                      r.newer_than          = time
         | 
| 90 | 
            +
                    end
         | 
| 91 | 
            +
                  )
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                # Limits the query to events that occurred on given time or earlier.
         | 
| 95 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 96 | 
            +
                #
         | 
| 97 | 
            +
                # @param time [Time]
         | 
| 98 | 
            +
                # @return [Specification]
         | 
| 99 | 
            +
                def newer_than_or_equal(time)
         | 
| 100 | 
            +
                  raise ArgumentError unless time.respond_to?(:to_time)
         | 
| 101 | 
            +
                  Specification.new(
         | 
| 102 | 
            +
                    reader,
         | 
| 103 | 
            +
                    result.dup do |r|
         | 
| 104 | 
            +
                      r.newer_than_or_equal = time
         | 
| 105 | 
            +
                      r.newer_than          = nil
         | 
| 106 | 
            +
                    end
         | 
| 107 | 
            +
                  )
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                # Limits the query to events within given time range.
         | 
| 111 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 112 | 
            +
                #
         | 
| 113 | 
            +
                # @param time_range [Range]
         | 
| 114 | 
            +
                # @return [Specification]
         | 
| 115 | 
            +
                def between(time_range)
         | 
| 116 | 
            +
                  if time_range.exclude_end?
         | 
| 117 | 
            +
                    newer_than_or_equal(time_range.first).older_than(time_range.last)
         | 
| 118 | 
            +
                  else
         | 
| 119 | 
            +
                    newer_than_or_equal(time_range.first).older_than_or_equal(time_range.last)
         | 
| 120 | 
            +
                  end
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                # Sets the order of time sorting using transaction time
         | 
| 124 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}
         | 
| 125 | 
            +
                #
         | 
| 126 | 
            +
                # @return [Specification]
         | 
| 127 | 
            +
                def as_at
         | 
| 128 | 
            +
                  Specification.new(reader, result.dup { |r| r.time_sort_by = :as_at})
         | 
| 129 | 
            +
                end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                # Sets the order of time sorting using validity time
         | 
| 132 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}
         | 
| 133 | 
            +
                #
         | 
| 134 | 
            +
                # @return [Specification]
         | 
| 135 | 
            +
                def as_of
         | 
| 136 | 
            +
                  Specification.new(reader, result.dup { |r| r.time_sort_by = :as_of })
         | 
| 137 | 
            +
                end
         | 
| 138 | 
            +
             | 
| 46 139 | 
             
                # Sets the order of reading events to ascending (forward from the start).
         | 
| 47 140 | 
             
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 48 141 | 
             
                #
         | 
| @@ -73,7 +166,7 @@ module RubyEventStore | |
| 73 166 | 
             
                # Yields each batch of records that was retrieved from the store.
         | 
| 74 167 | 
             
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 75 168 | 
             
                #
         | 
| 76 | 
            -
                # @yield [Array<Event | 
| 169 | 
            +
                # @yield [Array<Event>] batch of events
         | 
| 77 170 | 
             
                # @return [Enumerator, nil] Enumerator is returned when block not given
         | 
| 78 171 | 
             
                def each_batch
         | 
| 79 172 | 
             
                  return to_enum(:each_batch) unless block_given?
         | 
| @@ -87,7 +180,7 @@ module RubyEventStore | |
| 87 180 | 
             
                # Yields events read from the store if block given. Otherwise, returns enumerable collection.
         | 
| 88 181 | 
             
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 89 182 | 
             
                #
         | 
| 90 | 
            -
                # @yield [Event | 
| 183 | 
            +
                # @yield [Event] event
         | 
| 91 184 | 
             
                # @return [Enumerator, nil] Enumerator is returned when block not given
         | 
| 92 185 | 
             
                def each
         | 
| 93 186 | 
             
                  return to_enum unless block_given?
         | 
| @@ -111,7 +204,7 @@ module RubyEventStore | |
| 111 204 | 
             
                # built up to this point result using provided block.
         | 
| 112 205 | 
             
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 113 206 | 
             
                #
         | 
| 114 | 
            -
                # @accumulator starting state for reduce operation
         | 
| 207 | 
            +
                # @param accumulator starting state for reduce operation
         | 
| 115 208 | 
             
                # @return reduce result as defined by block given
         | 
| 116 209 | 
             
                def reduce(accumulator = nil, &block)
         | 
| 117 210 | 
             
                  raise ArgumentError.new("Block must be given") unless block_given?
         | 
| @@ -130,7 +223,7 @@ module RubyEventStore | |
| 130 223 | 
             
                # Returns array of domain events.
         | 
| 131 224 | 
             
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 132 225 | 
             
                #
         | 
| 133 | 
            -
                # @return [Array<Event | 
| 226 | 
            +
                # @return [Array<Event>]
         | 
| 134 227 | 
             
                def to_a
         | 
| 135 228 | 
             
                  each.to_a
         | 
| 136 229 | 
             
                end
         | 
| @@ -200,7 +293,7 @@ module RubyEventStore | |
| 200 293 | 
             
                # Limits the query to certain events by given even ids.
         | 
| 201 294 | 
             
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 202 295 | 
             
                #
         | 
| 203 | 
            -
                # @param  | 
| 296 | 
            +
                # @param event_ids [Array(String)] ids of event to look for.
         | 
| 204 297 | 
             
                # @return [Specification]
         | 
| 205 298 | 
             
                def with_id(event_ids)
         | 
| 206 299 | 
             
                  Specification.new(reader, result.dup{ |r| r.with_ids = event_ids })
         | 
| @@ -231,7 +324,7 @@ module RubyEventStore | |
| 231 324 | 
             
                # read from the store if block given. Otherwise, returns enumerable collection.
         | 
| 232 325 | 
             
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 233 326 | 
             
                #
         | 
| 234 | 
            -
                # @yield [Event | 
| 327 | 
            +
                # @yield [Event] event
         | 
| 235 328 | 
             
                # @return [Enumerator] Enumerator is returned when block not given
         | 
| 236 329 | 
             
                def events(event_ids)
         | 
| 237 330 | 
             
                  with_id(event_ids).each
         | 
| @@ -14,14 +14,14 @@ module RubyEventStore | |
| 14 14 | 
             
                # @private
         | 
| 15 15 | 
             
                def one(specification_result)
         | 
| 16 16 | 
             
                  record = repository.read(specification_result)
         | 
| 17 | 
            -
                  mapper. | 
| 17 | 
            +
                  mapper.record_to_event(record) if record
         | 
| 18 18 | 
             
                end
         | 
| 19 19 |  | 
| 20 20 | 
             
                # @api private
         | 
| 21 21 | 
             
                # @private
         | 
| 22 22 | 
             
                def each(specification_result)
         | 
| 23 23 | 
             
                  repository.read(specification_result).each do |batch|
         | 
| 24 | 
            -
                    yield batch.map { | | 
| 24 | 
            +
                    yield batch.map { |record| mapper.record_to_event(record) }
         | 
| 25 25 | 
             
                  end
         | 
| 26 26 | 
             
                end
         | 
| 27 27 |  | 
| @@ -5,14 +5,48 @@ module RubyEventStore | |
| 5 5 | 
             
                def initialize(direction: :forward,
         | 
| 6 6 | 
             
                               start: nil,
         | 
| 7 7 | 
             
                               stop: nil,
         | 
| 8 | 
            +
                               older_than: nil,
         | 
| 9 | 
            +
                               older_than_or_equal: nil,
         | 
| 10 | 
            +
                               newer_than: nil,
         | 
| 11 | 
            +
                               newer_than_or_equal: nil,
         | 
| 12 | 
            +
                               time_sort_by: nil,
         | 
| 8 13 | 
             
                               count: nil,
         | 
| 9 14 | 
             
                               stream: Stream.new(GLOBAL_STREAM),
         | 
| 10 15 | 
             
                               read_as: :all,
         | 
| 11 16 | 
             
                               batch_size: Specification::DEFAULT_BATCH_SIZE,
         | 
| 12 17 | 
             
                               with_ids: nil,
         | 
| 13 18 | 
             
                               with_types: nil)
         | 
| 14 | 
            -
                  @attributes = Struct.new( | 
| 15 | 
            -
                     | 
| 19 | 
            +
                  @attributes = Struct.new(
         | 
| 20 | 
            +
                    :direction,
         | 
| 21 | 
            +
                    :start,
         | 
| 22 | 
            +
                    :stop,
         | 
| 23 | 
            +
                    :older_than,
         | 
| 24 | 
            +
                    :older_than_or_equal,
         | 
| 25 | 
            +
                    :newer_than,
         | 
| 26 | 
            +
                    :newer_than_or_equal,
         | 
| 27 | 
            +
                    :time_sort_by,
         | 
| 28 | 
            +
                    :count,
         | 
| 29 | 
            +
                    :stream,
         | 
| 30 | 
            +
                    :read_as,
         | 
| 31 | 
            +
                    :batch_size,
         | 
| 32 | 
            +
                    :with_ids,
         | 
| 33 | 
            +
                    :with_types
         | 
| 34 | 
            +
                  ).new(
         | 
| 35 | 
            +
                    direction,
         | 
| 36 | 
            +
                    start,
         | 
| 37 | 
            +
                    stop,
         | 
| 38 | 
            +
                    older_than,
         | 
| 39 | 
            +
                    older_than_or_equal,
         | 
| 40 | 
            +
                    newer_than,
         | 
| 41 | 
            +
                    newer_than_or_equal,
         | 
| 42 | 
            +
                    time_sort_by,
         | 
| 43 | 
            +
                    count,
         | 
| 44 | 
            +
                    stream,
         | 
| 45 | 
            +
                    read_as,
         | 
| 46 | 
            +
                    batch_size,
         | 
| 47 | 
            +
                    with_ids,
         | 
| 48 | 
            +
                    with_types
         | 
| 49 | 
            +
                  )
         | 
| 16 50 | 
             
                  freeze
         | 
| 17 51 | 
             
                end
         | 
| 18 52 |  | 
| @@ -56,6 +90,46 @@ module RubyEventStore | |
| 56 90 | 
             
                  attributes.stop
         | 
| 57 91 | 
             
                end
         | 
| 58 92 |  | 
| 93 | 
            +
                # Ending time.
         | 
| 94 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 95 | 
            +
                #
         | 
| 96 | 
            +
                # @return [Time]
         | 
| 97 | 
            +
                def older_than
         | 
| 98 | 
            +
                  attributes.older_than
         | 
| 99 | 
            +
                end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                # Ending time.
         | 
| 102 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 103 | 
            +
                #
         | 
| 104 | 
            +
                # @return [Time]
         | 
| 105 | 
            +
                def older_than_or_equal
         | 
| 106 | 
            +
                  attributes.older_than_or_equal
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                # Starting time.
         | 
| 110 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 111 | 
            +
                #
         | 
| 112 | 
            +
                # @return [Time]
         | 
| 113 | 
            +
                def newer_than
         | 
| 114 | 
            +
                  attributes.newer_than
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                # Starting time.
         | 
| 118 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 119 | 
            +
                #
         | 
| 120 | 
            +
                # @return [Time]
         | 
| 121 | 
            +
                def newer_than_or_equal
         | 
| 122 | 
            +
                  attributes.newer_than_or_equal
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                # Time sorting strategy. Nil when not specified.
         | 
| 126 | 
            +
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 127 | 
            +
                #
         | 
| 128 | 
            +
                # @return [Symbol]
         | 
| 129 | 
            +
                def time_sort_by
         | 
| 130 | 
            +
                  attributes.time_sort_by
         | 
| 131 | 
            +
                end
         | 
| 132 | 
            +
             | 
| 59 133 | 
             
                # Read direction. True is reading forward
         | 
| 60 134 | 
             
                # {http://railseventstore.org/docs/read/ Find out more}.
         | 
| 61 135 | 
             
                #
         | 
| @@ -179,6 +253,11 @@ module RubyEventStore | |
| 179 253 | 
             
                # * direction
         | 
| 180 254 | 
             
                # * start
         | 
| 181 255 | 
             
                # * stop
         | 
| 256 | 
            +
                # * older_than
         | 
| 257 | 
            +
                # * older_than_or_equal
         | 
| 258 | 
            +
                # * newer_than
         | 
| 259 | 
            +
                # * newer_than_or_equal
         | 
| 260 | 
            +
                # * time_sort_by
         | 
| 182 261 | 
             
                # * count
         | 
| 183 262 | 
             
                # * stream
         | 
| 184 263 | 
             
                # * read_as
         | 
| @@ -193,6 +272,11 @@ module RubyEventStore | |
| 193 272 | 
             
                    get_direction,
         | 
| 194 273 | 
             
                    start,
         | 
| 195 274 | 
             
                    stop,
         | 
| 275 | 
            +
                    older_than,
         | 
| 276 | 
            +
                    older_than_or_equal,
         | 
| 277 | 
            +
                    newer_than,
         | 
| 278 | 
            +
                    newer_than_or_equal,
         | 
| 279 | 
            +
                    time_sort_by,
         | 
| 196 280 | 
             
                    limit,
         | 
| 197 281 | 
             
                    stream,
         | 
| 198 282 | 
             
                    attributes.read_as,
         | 
| @@ -4,14 +4,15 @@ require 'concurrent' | |
| 4 4 |  | 
| 5 5 | 
             
            module RubyEventStore
         | 
| 6 6 | 
             
              class Subscriptions
         | 
| 7 | 
            -
                def initialize
         | 
| 7 | 
            +
                def initialize(event_type_resolver: default_event_type_resolver)
         | 
| 8 | 
            +
                  @event_type_resolver = event_type_resolver
         | 
| 8 9 | 
             
                  @local  = LocalSubscriptions.new
         | 
| 9 10 | 
             
                  @global = GlobalSubscriptions.new
         | 
| 10 | 
            -
                  @thread | 
| 11 | 
            +
                  @thread = ThreadSubscriptions.new
         | 
| 11 12 | 
             
                end
         | 
| 12 13 |  | 
| 13 14 | 
             
                def add_subscription(subscriber, event_types)
         | 
| 14 | 
            -
                  local.add(subscriber, event_types)
         | 
| 15 | 
            +
                  local.add(subscriber, resolve_event_types(event_types))
         | 
| 15 16 | 
             
                end
         | 
| 16 17 |  | 
| 17 18 | 
             
                def add_global_subscription(subscriber)
         | 
| @@ -19,7 +20,7 @@ module RubyEventStore | |
| 19 20 | 
             
                end
         | 
| 20 21 |  | 
| 21 22 | 
             
                def add_thread_subscription(subscriber, event_types)
         | 
| 22 | 
            -
                  thread.local.add(subscriber, event_types)
         | 
| 23 | 
            +
                  thread.local.add(subscriber, resolve_event_types(event_types))
         | 
| 23 24 | 
             
                end
         | 
| 24 25 |  | 
| 25 26 | 
             
                def add_thread_global_subscription(subscriber)
         | 
| @@ -27,12 +28,25 @@ module RubyEventStore | |
| 27 28 | 
             
                end
         | 
| 28 29 |  | 
| 29 30 | 
             
                def all_for(event_type)
         | 
| 30 | 
            -
                   | 
| 31 | 
            +
                  resolved_event_type = resolve_event_type(event_type)
         | 
| 32 | 
            +
                  [local, global, thread].map{|r| r.all_for(resolved_event_type)}.reduce(&:+)
         | 
| 31 33 | 
             
                end
         | 
| 32 34 |  | 
| 33 35 | 
             
                private
         | 
| 34 36 | 
             
                attr_reader :local, :global, :thread
         | 
| 35 37 |  | 
| 38 | 
            +
                def default_event_type_resolver
         | 
| 39 | 
            +
                  ->(value) { value.to_s }
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def resolve_event_types(event_types)
         | 
| 43 | 
            +
                  event_types.map(&method(:resolve_event_type))
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def resolve_event_type(type)
         | 
| 47 | 
            +
                  @event_type_resolver.call(type)
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 36 50 | 
             
                class ThreadSubscriptions
         | 
| 37 51 | 
             
                  def initialize
         | 
| 38 52 | 
             
                    @local  = ThreadLocalSubscriptions.new
         | 
| @@ -51,8 +65,8 @@ module RubyEventStore | |
| 51 65 | 
             
                  end
         | 
| 52 66 |  | 
| 53 67 | 
             
                  def add(subscription, event_types)
         | 
| 54 | 
            -
                    event_types.each{ |type| @subscriptions[type | 
| 55 | 
            -
                    ->() {event_types.each{ |type| @subscriptions.fetch(type | 
| 68 | 
            +
                    event_types.each{ |type| @subscriptions[type] << subscription }
         | 
| 69 | 
            +
                    ->() {event_types.each{ |type| @subscriptions.fetch(type).delete(subscription) } }
         | 
| 56 70 | 
             
                  end
         | 
| 57 71 |  | 
| 58 72 | 
             
                  def all_for(event_type)
         | 
| @@ -83,8 +97,8 @@ module RubyEventStore | |
| 83 97 | 
             
                  end
         | 
| 84 98 |  | 
| 85 99 | 
             
                  def add(subscription, event_types)
         | 
| 86 | 
            -
                    event_types.each{ |type| @subscriptions.value[type | 
| 87 | 
            -
                    ->() {event_types.each{ |type| @subscriptions.value.fetch(type | 
| 100 | 
            +
                    event_types.each{ |type| @subscriptions.value[type] << subscription }
         | 
| 101 | 
            +
                    ->() {event_types.each{ |type| @subscriptions.value.fetch(type).delete(subscription) } }
         | 
| 88 102 | 
             
                  end
         | 
| 89 103 |  | 
| 90 104 | 
             
                  def all_for(event_type)
         | 
| @@ -4,23 +4,23 @@ module RubyEventStore | |
| 4 4 | 
             
              class TransformKeys
         | 
| 5 5 | 
             
                class << self
         | 
| 6 6 | 
             
                  def stringify(data)
         | 
| 7 | 
            -
                     | 
| 7 | 
            +
                    deep_transform(data, &:to_s)
         | 
| 8 8 | 
             
                  end
         | 
| 9 9 |  | 
| 10 10 | 
             
                  def symbolize(data)
         | 
| 11 | 
            -
                     | 
| 11 | 
            +
                    deep_transform(data, &:to_sym)
         | 
| 12 12 | 
             
                  end
         | 
| 13 13 |  | 
| 14 14 | 
             
                  private
         | 
| 15 15 |  | 
| 16 | 
            -
                  def  | 
| 16 | 
            +
                  def deep_transform(data, &block)
         | 
| 17 17 | 
             
                    data.each_with_object({}) do |(k, v), h|
         | 
| 18 18 | 
             
                      h[yield(k)] =
         | 
| 19 19 | 
             
                        case v
         | 
| 20 20 | 
             
                        when Hash
         | 
| 21 | 
            -
                           | 
| 21 | 
            +
                          deep_transform(v, &block)
         | 
| 22 22 | 
             
                        when Array
         | 
| 23 | 
            -
                          v.map{|i| Hash === i ?  | 
| 23 | 
            +
                          v.map{|i| Hash === i ? deep_transform(i, &block) : i}
         | 
| 24 24 | 
             
                        else
         | 
| 25 25 | 
             
                          v
         | 
| 26 26 | 
             
                        end
         |