funes-rails 0.1.0 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b28b73445f6209c360034c351b80e0677356b42c14834908e9598a6b6f7edd02
4
- data.tar.gz: 7587dfa95f04e2e2a1b0eb505c19f0433541b2c46fa49e83471dee1386fec79b
3
+ metadata.gz: f475c7d974c06b8ea3700459a6275484b805cab6b5e5ca1822eb33a09bb5b92e
4
+ data.tar.gz: 1ee86eb626084ddf73cfb3921abf3e4a68ab823ad87ff09fd890788ced2063fc
5
5
  SHA512:
6
- metadata.gz: 828e4c5762de480e79f264124d12e7d4792ffc4856c3941dc4e757b8ebc9a31e0e645af98113a127df5f0d22f38398fe6a3c1e50511a9e59cd7e59b9cf05d8fd
7
- data.tar.gz: 9feb8d0618335d5d1eb23027d5ec50cea4b91753b016bfe0b2cea3ba3567dfe43303f8173c07f06857b62e0aaa71ba3da33ba625bf5b4a35afb655a649b18254
6
+ metadata.gz: 5bc8898e1014eee4e865c6b1747f640a70f5cbf9336d5356eaa52ef9a557845764ac831ad54d1c5e3e777104c14b44aa5d737be3fb9f12597e5550e4280c4481
7
+ data.tar.gz: bbee4693d75aa24d31133e3738876d6ee0906cbde3fef4eb915d47d0ae74dad5ec91f8787d0eb2293660b9a52d632fa5af44b973a3b22ddcdd685dee7875d9dc
data/Rakefile CHANGED
@@ -10,8 +10,11 @@ require "bundler/gem_tasks"
10
10
  namespace :docs do
11
11
  desc "Generate YARD documentation for current version"
12
12
  task :generate do
13
- require_relative "lib/funes/version"
14
- version = Funes::VERSION
13
+ # Allow version override via environment variable (for CI)
14
+ version = ENV["VERSION"] || begin
15
+ require_relative "lib/funes/version"
16
+ Funes::VERSION
17
+ end
15
18
  output_dir = "docs/v#{version}"
16
19
 
17
20
  puts "Generating documentation for version #{version}..."
@@ -31,6 +34,8 @@ namespace :docs do
31
34
 
32
35
  desc "Build version selector index page"
33
36
  task :build_index do
37
+ require "erb"
38
+
34
39
  versions = Dir.glob("docs/v*").map { |d| File.basename(d) }.sort.reverse
35
40
 
36
41
  if versions.empty?
@@ -39,86 +44,21 @@ namespace :docs do
39
44
  end
40
45
 
41
46
  latest_version = versions.first
42
-
43
- html = <<~HTML
44
- <!DOCTYPE html>
45
- <html>
46
- <head>
47
- <meta charset="utf-8">
48
- <title>Funes Documentation</title>
49
- <link rel="stylesheet" href="css/style.css">
50
- <style>
51
- body {
52
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
53
- max-width: 800px;
54
- margin: 50px auto;
55
- padding: 20px;
56
- line-height: 1.6;
57
- }
58
- h1 {
59
- color: #333;
60
- border-bottom: 2px solid #0066cc;
61
- padding-bottom: 10px;
62
- }
63
- .version-list {
64
- list-style: none;
65
- padding: 0;
66
- }
67
- .version-list li {
68
- margin: 10px 0;
69
- padding: 15px;
70
- background: #f5f5f5;
71
- border-radius: 5px;
72
- }
73
- .version-list a {
74
- text-decoration: none;
75
- color: #0066cc;
76
- font-size: 18px;
77
- font-weight: 500;
78
- }
79
- .version-list a:hover {
80
- text-decoration: underline;
81
- }
82
- .latest-badge {
83
- background: #0066cc;
84
- color: white;
85
- padding: 3px 8px;
86
- border-radius: 3px;
87
- font-size: 12px;
88
- margin-left: 10px;
89
- }
90
- .description {
91
- color: #666;
92
- margin-top: 20px;
93
- }
94
- </style>
95
- </head>
96
- <body>
97
- <h1>Funes Documentation</h1>
98
- <p class="description">Event Sourcing for Rails - Select a version to view documentation</p>
99
-
100
- <ul class="version-list">
101
- HTML
102
-
103
- versions.each do |version|
104
- is_latest = version == latest_version
105
- badge = is_latest ? '<span class="latest-badge">latest</span>' : ''
106
- html += " <li><a href=\"#{version}/index.html\">#{version}#{badge}</a></li>\n"
107
- end
108
-
109
- html += <<~HTML
110
- </ul>
111
-
112
- <p class="description">
113
- <a href="https://github.com/funes-org/funes">View on GitHub</a> |
114
- <a href="https://funes.org/">Official Website</a>
115
- </p>
116
- </body>
117
- </html>
118
- HTML
47
+ template_path = File.expand_path("lib/templates/docs_index.html.erb", __dir__)
48
+ template = ERB.new(File.read(template_path))
49
+ html = template.result(binding)
119
50
 
120
51
  File.write("docs/index.html", html)
121
52
  puts "Version index page created at docs/index.html"
53
+
54
+ # Create CNAME file for GitHub Pages custom domain
55
+ File.write("docs/CNAME", "docs.funes.org\n")
56
+ puts "CNAME file created for docs.funes.org"
57
+
58
+ # Create .nojekyll file to bypass Jekyll processing
59
+ # This is required for YARD's _index.html file to work properly
60
+ File.write("docs/.nojekyll", "")
61
+ puts ".nojekyll file created to bypass Jekyll processing"
122
62
  end
123
63
 
124
64
  desc "List all documented versions"
@@ -165,14 +165,18 @@ module Funes
165
165
  return new_event unless new_event.valid?
166
166
  return new_event if consistency_projection.present? &&
167
167
  compute_projection_with_new_event(consistency_projection, new_event).invalid?
168
- begin
169
- @instance_new_events << new_event.persist!(@idx, incremented_version)
170
- rescue ActiveRecord::RecordNotUnique
171
- new_event.errors.add(:base, I18n.t("funes.events.racing_condition_on_insert"))
168
+
169
+ ActiveRecord::Base.transaction do
170
+ begin
171
+ @instance_new_events << new_event.persist!(@idx, incremented_version)
172
+ run_transactional_projections
173
+ rescue ActiveRecord::RecordNotUnique, Funes::TransactionalProjectionFailed
174
+ new_event.errors.add(:base, I18n.t("funes.events.racing_condition_on_insert"))
175
+ raise ActiveRecord::Rollback
176
+ end
172
177
  end
173
178
 
174
- run_transactional_projections
175
- schedule_async_projections
179
+ schedule_async_projections unless new_event.errors.any?
176
180
 
177
181
  new_event
178
182
  end
@@ -202,8 +206,12 @@ module Funes
202
206
 
203
207
  private
204
208
  def run_transactional_projections
205
- transactional_projections.each do |projection_class|
206
- Funes::PersistProjectionJob.perform_now(@idx, projection_class, last_event_creation_date)
209
+ begin
210
+ transactional_projections.each do |projection_class|
211
+ Funes::PersistProjectionJob.perform_now(@idx, projection_class, last_event_creation_date)
212
+ end
213
+ rescue ActiveRecord::StatementInvalid => e
214
+ raise Funes::TransactionalProjectionFailed, e.message
207
215
  end
208
216
  end
209
217
 
@@ -0,0 +1,17 @@
1
+ module Funes
2
+ # Raised when a transactional projection fails due to a database constraint violation.
3
+ #
4
+ # This error wraps database-level errors (like NOT NULL violations, unique constraint
5
+ # violations, etc.) that occur during the persistence of a transactional projection.
6
+ # When this happens, the entire transaction (including the event) is rolled back.
7
+ #
8
+ # @example Handling projection failures
9
+ # stream = OrderEventStream.for("order-123")
10
+ # event = stream.append!(Order::Placed.new(total: 99.99))
11
+ #
12
+ # if event.errors[:base].present?
13
+ # # The projection failed and transaction was rolled back
14
+ # Rails.logger.error "Projection failed: #{event.errors.full_messages}"
15
+ # end
16
+ class TransactionalProjectionFailed < StandardError; end
17
+ end
data/lib/funes/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Funes
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,37 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="refresh" content="0; url=<%= latest_version %>/index.html">
6
+ <title>Funes Documentation</title>
7
+ <style>
8
+ body {
9
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
10
+ max-width: 800px;
11
+ margin: 50px auto;
12
+ padding: 20px;
13
+ text-align: center;
14
+ }
15
+ .message {
16
+ margin-top: 100px;
17
+ color: #666;
18
+ }
19
+ a {
20
+ color: #0066cc;
21
+ text-decoration: none;
22
+ }
23
+ a:hover {
24
+ text-decoration: underline;
25
+ }
26
+ </style>
27
+ <script>
28
+ window.location.href = "<%= latest_version %>/index.html";
29
+ </script>
30
+ </head>
31
+ <body>
32
+ <div class="message">
33
+ <p>Redirecting to the latest version (<%= latest_version %>)...</p>
34
+ <p>If you are not redirected, <a href="<%= latest_version %>/index.html">click here</a>.</p>
35
+ </div>
36
+ </body>
37
+ </html>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: funes-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vinícius Almeida da Silva
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-01-07 00:00:00.000000000 Z
11
+ date: 2026-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -50,12 +50,14 @@ files:
50
50
  - config/routes.rb
51
51
  - lib/funes.rb
52
52
  - lib/funes/engine.rb
53
+ - lib/funes/transactional_projection_failed.rb
53
54
  - lib/funes/unknown_event.rb
54
55
  - lib/funes/unknown_materialization_model.rb
55
56
  - lib/funes/version.rb
56
57
  - lib/generators/funes/install_generator.rb
57
58
  - lib/generators/funes/templates/migration.rb.tt
58
59
  - lib/tasks/funes_tasks.rake
60
+ - lib/templates/docs_index.html.erb
59
61
  homepage: https://funes.org/
60
62
  licenses:
61
63
  - MIT