rails_simple_event_sourcing 1.0.6 → 1.0.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f612b51a40ff345ec42bb1fbc1aa60f7444278e4d7e8adca318fbf9ae3d6676e
4
- data.tar.gz: 4e62dd3f13548750d95309e729537e1681c2630f05a901702d2e4afe96f48971
3
+ metadata.gz: 9415504de52817629c90a90ad0fff708ad8f829c768ed88485b8eae53f241c18
4
+ data.tar.gz: 2344f7a06e5c3b9dca5d0b6c98b1526ad73088c59cde9a0c64f2b5cb6a227ec6
5
5
  SHA512:
6
- metadata.gz: fbd0a8385be3282c59d0c29908b65eb209f82a4a6978e9f614f72de8ebe5ed06b1c88daa4e6975cab94e3c5f4e9e9e3b00d8c977d7c46f64642e2c7eadde2c8e
7
- data.tar.gz: e2552009f821e2e71e0c72f274c5dd1056465c1f1cc991100320f08152be6db7df4f874e83439ad29408779cac02877b851e9ebb5204b6be6f03da76ada8d03c
6
+ metadata.gz: 3f2ec958c3dab2f9b398ed1bd0bfddec38fb13c720762ab57cc45c59091d9116f07af133601a19dae083ba5c40b32177cbfaa4809cb6af1a37cf569ed941693d
7
+ data.tar.gz: 32b8d673ca804d1ef03e5e55a561011fd052d70789afc078b9f8c7becff373d310bb2d24da411e6fc8a2fa869720a3aad487fbc4a93c5290cc2ce9a4f4d81c4d
data/README.md CHANGED
@@ -88,6 +88,9 @@ RailsSimpleEventSourcing.configure do |config|
88
88
  # When true, falls back to convention-based handler resolution
89
89
  # When false, requires explicit registration of all handlers
90
90
  config.use_naming_convention_fallback = true
91
+
92
+ # Number of events displayed per page in the Events Viewer (defaults to 25)
93
+ config.events_per_page = 50
91
94
  end
92
95
  ```
93
96
 
@@ -561,11 +564,11 @@ In production you will likely want to restrict access to the events viewer.
561
564
  Rails.application.routes.draw do
562
565
  mount Rack::Auth::Basic.new(
563
566
  RailsSimpleEventSourcing::Engine,
564
- "Event Sourcing"
567
+ "Event Store"
565
568
  ) { |username, password|
566
569
  ActiveSupport::SecurityUtils.secure_compare(username, "admin") &
567
570
  ActiveSupport::SecurityUtils.secure_compare(password, Rails.application.credentials.event_sourcing_password || "secret")
568
- }, at: "/event-sourcing"
571
+ }, at: "/event-store"
569
572
  end
570
573
  ```
571
574
 
@@ -587,16 +590,6 @@ end
587
590
  - **Filtering** - Filter events by event type or aggregate type using dropdown selectors
588
591
  - **Search** - Search by aggregate ID, or use `key:value` syntax to search within payload and metadata (e.g., `email:john@example.com`)
589
592
 
590
- **Configuration:**
591
-
592
- You can configure the number of events displayed per page (defaults to 25):
593
-
594
- ```ruby
595
- RailsSimpleEventSourcing.configure do |config|
596
- config.events_per_page = 50
597
- end
598
- ```
599
-
600
593
  ### Model Configuration
601
594
 
602
595
  Models that use event sourcing should include the `RailsSimpleEventSourcing::Events` module:
@@ -3,9 +3,9 @@
3
3
  module RailsSimpleEventSourcing
4
4
  class EventsController < ApplicationController
5
5
  def index
6
- load_filter_options
7
- scope = search_events
8
- paginate(scope)
6
+ @event_types = event_types
7
+ @aggregates = aggregates
8
+ paginate(search_events)
9
9
  end
10
10
 
11
11
  def show
@@ -16,15 +16,21 @@ module RailsSimpleEventSourcing
16
16
 
17
17
  private
18
18
 
19
- def load_filter_options
20
- @event_types = Event.distinct.pluck(:event_type).sort
21
- @aggregates = Event.where.not(eventable_type: nil).distinct.pluck(:eventable_type).sort
19
+ def event_types
20
+ return Event.descendants.map(&:name).sort if Rails.env.production?
21
+
22
+ Event.distinct.pluck(:event_type).sort
23
+ end
24
+
25
+ def aggregates
26
+ return Event.descendants.filter_map(&:aggregate_class).map(&:name).uniq.sort if Rails.env.production?
27
+
28
+ Event.where.not(eventable_type: nil).distinct.pluck(:eventable_type).sort
22
29
  end
23
30
 
24
31
  def search_events
25
- scope = Event.order(created_at: :desc)
26
32
  EventSearch.new(
27
- scope:,
33
+ scope: Event.all,
28
34
  event_type: params[:event_type],
29
35
  aggregate: params[:aggregate],
30
36
  query: params[:q]
@@ -34,8 +40,9 @@ module RailsSimpleEventSourcing
34
40
  def paginate(scope)
35
41
  @paginator = Paginator.new(
36
42
  scope:,
37
- page: params[:page],
38
- per_page: RailsSimpleEventSourcing.config.events_per_page
43
+ per_page: RailsSimpleEventSourcing.config.events_per_page,
44
+ cursor: params[:after] || params[:before],
45
+ direction: params[:before].present? ? :prev : :next
39
46
  )
40
47
  end
41
48
 
@@ -2,26 +2,5 @@
2
2
 
3
3
  module RailsSimpleEventSourcing
4
4
  module EventsHelper
5
- def pagination_window(current_page, total_pages, window: 2) # rubocop:disable Metrics/MethodLength
6
- return [1] if total_pages <= 1
7
-
8
- pages = []
9
- left = [current_page - window, 1].max
10
- right = [current_page + window, total_pages].min
11
-
12
- if left > 1
13
- pages << 1
14
- pages << :gap if left > 2
15
- end
16
-
17
- (left..right).each { |p| pages << p }
18
-
19
- if right < total_pages
20
- pages << :gap if right < total_pages - 1
21
- pages << total_pages
22
- end
23
-
24
- pages
25
- end
26
5
  end
27
6
  end
@@ -1,23 +1,13 @@
1
- <% if @paginator.total_pages > 1 %>
1
+ <% if @paginator.prev? || @paginator.next? %>
2
2
  <nav class="pagination">
3
- <% if @paginator.current_page > 1 %>
4
- <%= link_to "Prev", events_path(page: @paginator.current_page - 1, q: params[:q], event_type: params[:event_type], aggregate: params[:aggregate]) %>
3
+ <% if @paginator.prev? %>
4
+ <%= link_to "Prev", events_path(before: @paginator.prev_cursor, q: params[:q], event_type: params[:event_type], aggregate: params[:aggregate]) %>
5
5
  <% else %>
6
6
  <span class="disabled">Prev</span>
7
7
  <% end %>
8
8
 
9
- <% pagination_window(@paginator.current_page, @paginator.total_pages).each do |page| %>
10
- <% if page == :gap %>
11
- <span class="gap">&hellip;</span>
12
- <% elsif page == @paginator.current_page %>
13
- <span class="current"><%= page %></span>
14
- <% else %>
15
- <%= link_to page, events_path(page: page, q: params[:q], event_type: params[:event_type], aggregate: params[:aggregate]) %>
16
- <% end %>
17
- <% end %>
18
-
19
- <% if @paginator.current_page < @paginator.total_pages %>
20
- <%= link_to "Next", events_path(page: @paginator.current_page + 1, q: params[:q], event_type: params[:event_type], aggregate: params[:aggregate]) %>
9
+ <% if @paginator.next? %>
10
+ <%= link_to "Next", events_path(after: @paginator.next_cursor, q: params[:q], event_type: params[:event_type], aggregate: params[:aggregate]) %>
21
11
  <% else %>
22
12
  <span class="disabled">Next</span>
23
13
  <% end %>
@@ -10,8 +10,7 @@
10
10
 
11
11
  <div class="card">
12
12
  <div class="info-bar">
13
- <span><%= @paginator.total_count %> event<%= @paginator.total_count == 1 ? "" : "s" %> found</span>
14
- <span>Page <%= @paginator.current_page %> of <%= @paginator.total_pages %></span>
13
+ <span>Events</span>
15
14
  </div>
16
15
 
17
16
  <table>
@@ -1,4 +1,4 @@
1
- <%= link_to "&larr; Back to events".html_safe, events_path(q: params[:q], page: params[:page]), class: "back-link" %>
1
+ <%= link_to "&larr; Back to events".html_safe, events_path(q: params[:q]), class: "back-link" %>
2
2
 
3
3
  <div class="card">
4
4
  <dl class="detail-grid">
@@ -2,18 +2,68 @@
2
2
 
3
3
  module RailsSimpleEventSourcing
4
4
  class Paginator
5
- attr_reader :total_count, :total_pages, :current_page, :per_page
5
+ attr_reader :per_page
6
6
 
7
- def initialize(scope:, page:, per_page:)
7
+ def initialize(scope:, per_page:, cursor: nil, direction: :next)
8
8
  @scope = scope
9
9
  @per_page = per_page
10
- @total_count = scope.count
11
- @total_pages = [(@total_count.to_f / per_page).ceil, 1].max
12
- @current_page = (page.presence || 1).to_i.clamp(1, @total_pages)
10
+ @cursor = cursor&.to_i
11
+ @direction = direction
13
12
  end
14
13
 
15
14
  def records
16
- @scope.offset((@current_page - 1) * @per_page).limit(@per_page)
15
+ @records ||= fetch_records
16
+ end
17
+
18
+ def next_cursor
19
+ records.last&.id
20
+ end
21
+
22
+ def prev_cursor
23
+ records.first&.id
24
+ end
25
+
26
+ def next?
27
+ records
28
+ @has_next
29
+ end
30
+
31
+ def prev?
32
+ records
33
+ @has_prev
34
+ end
35
+
36
+ private
37
+
38
+ def fetch_records
39
+ if @cursor.nil?
40
+ fetch_first_page
41
+ elsif @direction == :prev
42
+ fetch_prev_page
43
+ else
44
+ fetch_next_page
45
+ end
46
+ end
47
+
48
+ def fetch_first_page
49
+ rows = @scope.order(id: :desc).limit(@per_page + 1).to_a
50
+ @has_prev = false
51
+ @has_next = rows.size > @per_page
52
+ rows.first(@per_page)
53
+ end
54
+
55
+ def fetch_next_page
56
+ rows = @scope.where(id: ...@cursor).order(id: :desc).limit(@per_page + 1).to_a
57
+ @has_prev = true
58
+ @has_next = rows.size > @per_page
59
+ rows.first(@per_page)
60
+ end
61
+
62
+ def fetch_prev_page
63
+ rows = @scope.where('id > ?', @cursor).order(id: :asc).limit(@per_page + 1).to_a
64
+ @has_next = true
65
+ @has_prev = rows.size > @per_page
66
+ rows.first(@per_page).reverse
17
67
  end
18
68
  end
19
69
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsSimpleEventSourcing
4
- VERSION = '1.0.6'
4
+ VERSION = '1.0.7'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_simple_event_sourcing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damian Baćkowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-02-15 00:00:00.000000000 Z
11
+ date: 2026-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg