solid_objects 0.12.0 → 0.13.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -0
  3. data/README.md +72 -6
  4. data/app/models/solid_objects/broadcast.rb +8 -0
  5. data/docs/adr/0009-realtime-updates.md +5 -1
  6. data/docs/architecture.md +4 -2
  7. data/docs/authorization.md +11 -4
  8. data/docs/correctness.md +3 -3
  9. data/docs/dashboard.md +200 -0
  10. data/docs/database-schema.md +5 -4
  11. data/docs/development.md +12 -0
  12. data/docs/realtime.md +37 -7
  13. data/docs/roadmap.md +28 -6
  14. data/docs/security.md +8 -0
  15. data/examples/application/README.md +5 -5
  16. data/examples/application/app/actors/chat_room_actor.rb +1 -1
  17. data/examples/application/app/actors/shopping_cart_actor.rb +5 -5
  18. data/lib/solid_objects/actor.rb +6 -5
  19. data/lib/solid_objects/actor_channel.rb +7 -4
  20. data/lib/solid_objects/actor_definition.rb +15 -3
  21. data/lib/solid_objects/actor_view.rb +6 -1
  22. data/lib/solid_objects/effect_executor.rb +10 -2
  23. data/lib/solid_objects/errors.rb +3 -0
  24. data/lib/solid_objects/executor.rb +7 -1
  25. data/lib/solid_objects/reminder_scheduler.rb +28 -14
  26. data/lib/solid_objects/test_helper.rb +16 -0
  27. data/lib/solid_objects/turbo_stream_renderer.rb +3 -3
  28. data/lib/solid_objects/version.rb +1 -1
  29. data/lib/solid_objects/web/action.rb +109 -0
  30. data/lib/solid_objects/web/application.rb +239 -0
  31. data/lib/solid_objects/web/csrf_protection.rb +130 -0
  32. data/lib/solid_objects/web/helpers.rb +227 -0
  33. data/lib/solid_objects/web/paginator.rb +64 -0
  34. data/lib/solid_objects/web/route.rb +55 -0
  35. data/lib/solid_objects/web/router.rb +46 -0
  36. data/lib/solid_objects/web/statistics.rb +78 -0
  37. data/lib/solid_objects/web.rb +222 -0
  38. data/sig/generated/lib/solid_objects/actor.rbs +2 -2
  39. data/sig/generated/lib/solid_objects/actor_definition.rbs +9 -2
  40. data/sig/generated/lib/solid_objects/errors.rbs +3 -0
  41. data/sig/generated/lib/solid_objects/reminder_scheduler.rbs +9 -6
  42. data/sig/generated/lib/solid_objects/test_helper.rbs +3 -0
  43. data/sig/generated/lib/solid_objects/web/action.rbs +78 -0
  44. data/sig/generated/lib/solid_objects/web/application.rbs +50 -0
  45. data/sig/generated/lib/solid_objects/web/csrf_protection.rbs +55 -0
  46. data/sig/generated/lib/solid_objects/web/helpers.rbs +118 -0
  47. data/sig/generated/lib/solid_objects/web/paginator.rbs +54 -0
  48. data/sig/generated/lib/solid_objects/web/route.rbs +45 -0
  49. data/sig/generated/lib/solid_objects/web/router.rbs +29 -0
  50. data/sig/generated/lib/solid_objects/web/statistics.rbs +46 -0
  51. data/sig/generated/lib/solid_objects/web.rbs +129 -0
  52. data/sig/generated/models/solid_objects/broadcast.rbs +2 -0
  53. data/web/assets/javascripts/application.js +118 -0
  54. data/web/assets/javascripts/charts.js +190 -0
  55. data/web/assets/stylesheets/application.css +527 -0
  56. data/web/views/_messages.erb +29 -0
  57. data/web/views/_navigation.erb +15 -0
  58. data/web/views/_paging.erb +17 -0
  59. data/web/views/_status_filter.erb +8 -0
  60. data/web/views/_summary.erb +39 -0
  61. data/web/views/broadcasts.erb +35 -0
  62. data/web/views/dashboard.erb +128 -0
  63. data/web/views/dead_letter.erb +40 -0
  64. data/web/views/dead_letters.erb +42 -0
  65. data/web/views/effects.erb +35 -0
  66. data/web/views/instance.erb +139 -0
  67. data/web/views/instances.erb +49 -0
  68. data/web/views/layout.erb +22 -0
  69. data/web/views/mailbox.erb +35 -0
  70. data/web/views/message.erb +34 -0
  71. data/web/views/processes.erb +37 -0
  72. data/web/views/reminders.erb +37 -0
  73. metadata +55 -2
@@ -0,0 +1,34 @@
1
+ <section class="panel">
2
+ <div class="panel-head">
3
+ <h2><%= h(@message.operation) %></h2>
4
+ <div class="actions">
5
+ <%= status_label(@message.delivery_mode) %>
6
+ <a href="<%= h(path_to("/instances/#{@message.instance_id}")) %>"><%= actor_label(@message) %></a>
7
+ </div>
8
+ </div>
9
+
10
+ <dl class="attributes">
11
+ <div><dt>Sequence</dt><dd><%= number(@message.sequence) %></dd></div>
12
+ <div><dt>Attempts</dt><dd><%= number(@message.attempt_count) %> / <%= number(@message.max_attempts) %></dd></div>
13
+ <div><dt>Request id</dt><dd><%= h(@message.request_id) %></dd></div>
14
+ <div><dt>Idempotency key</dt><dd><%= h(@message.idempotency_key || "none") %></dd></div>
15
+ <div><dt>Enqueued</dt><dd><%= relative_time(@message.enqueued_at) %></dd></div>
16
+ <div><dt>Available</dt><dd><%= relative_time(@message.available_at) %></dd></div>
17
+ <div><dt>Started</dt><dd><%= relative_time(@message.started_at) %></dd></div>
18
+ <div><dt>Completed</dt><dd><%= relative_time(@message.completed_at) %></dd></div>
19
+ <div><dt>Rejected</dt><dd><%= relative_time(@message.rejected_at) %></dd></div>
20
+ <div><dt>Last failed</dt><dd><%= relative_time(@message.last_failed_at) %></dd></div>
21
+ </dl>
22
+
23
+ <h3>Arguments</h3>
24
+ <%= json_block(@message.arguments) %>
25
+
26
+ <h3>Result</h3>
27
+ <%= json_block(@message.result) %>
28
+
29
+ <h3>Error</h3>
30
+ <%= json_block(@message.error) %>
31
+
32
+ <h3>Rejection</h3>
33
+ <%= json_block(@message.rejection) %>
34
+ </section>
@@ -0,0 +1,37 @@
1
+ <section class="panel">
2
+ <h2>Processes</h2>
3
+ <%= erb(:_status_filter, statuses: SolidObjects::Web::Statistics::PROCESS_STATES, selected: @status) %>
4
+
5
+ <% if @paginator.records.empty? %>
6
+ <p class="empty">No process matches this filter.</p>
7
+ <% else %>
8
+ <table>
9
+ <thead>
10
+ <tr>
11
+ <th>Kind</th>
12
+ <th>Host</th>
13
+ <th>PID</th>
14
+ <th>State</th>
15
+ <th>Started</th>
16
+ <th>Last heartbeat</th>
17
+ <th>Activated instances</th>
18
+ </tr>
19
+ </thead>
20
+ <tbody>
21
+ <% @paginator.records.each do |process_record| %>
22
+ <tr>
23
+ <td><%= h(process_record.kind) %></td>
24
+ <td><%= h(process_record.hostname) %></td>
25
+ <td><%= h(process_record.pid) %></td>
26
+ <td><%= status_label(process_record.shutdown_state) %></td>
27
+ <td><%= relative_time(process_record.started_at) %></td>
28
+ <td><%= relative_time(process_record.last_heartbeat_at) %></td>
29
+ <td><%= number(@activated_counts.fetch(process_record.id, 0)) %></td>
30
+ </tr>
31
+ <% end %>
32
+ </tbody>
33
+ </table>
34
+ <% end %>
35
+
36
+ <%= erb(:_paging) %>
37
+ </section>
@@ -0,0 +1,37 @@
1
+ <section class="panel">
2
+ <h2>Reminders</h2>
3
+ <%= erb(:_status_filter, statuses: SolidObjects::Web::Statistics::REMINDER_STATUSES, selected: @status) %>
4
+
5
+ <% if @paginator.records.empty? %>
6
+ <p class="empty">No reminder matches this filter.</p>
7
+ <% else %>
8
+ <table>
9
+ <thead>
10
+ <tr>
11
+ <th>Actor</th>
12
+ <th>Name</th>
13
+ <th>Operation</th>
14
+ <th>Status</th>
15
+ <th>Next run</th>
16
+ <th>Interval</th>
17
+ <th>Occurrence</th>
18
+ </tr>
19
+ </thead>
20
+ <tbody>
21
+ <% @paginator.records.each do |reminder| %>
22
+ <tr>
23
+ <td><a href="<%= h(path_to("/instances/#{reminder.instance_id}")) %>"><%= actor_label(reminder) %></a></td>
24
+ <td><%= h(reminder.name) %></td>
25
+ <td><%= h(reminder.operation) %></td>
26
+ <td><%= status_label(reminder.status) %></td>
27
+ <td><%= relative_time(reminder.next_run_at) %></td>
28
+ <td><%= duration(reminder.interval_seconds) %></td>
29
+ <td><%= number(reminder.occurrence) %></td>
30
+ </tr>
31
+ <% end %>
32
+ </tbody>
33
+ </table>
34
+ <% end %>
35
+
36
+ <%= erb(:_paging) %>
37
+ </section>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Carlson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-08-13 00:00:00.000000000 Z
11
+ date: 2026-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actioncable
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '8.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '3.1'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '3.1'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: railties
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -330,6 +344,7 @@ files:
330
344
  - docs/authorization.md
331
345
  - docs/benchmarks.md
332
346
  - docs/correctness.md
347
+ - docs/dashboard.md
333
348
  - docs/database-schema.md
334
349
  - docs/development.md
335
350
  - docs/fit.md
@@ -424,6 +439,15 @@ files:
424
439
  - lib/solid_objects/wake_up_adapters.rb
425
440
  - lib/solid_objects/wake_up_adapters/postgresql.rb
426
441
  - lib/solid_objects/wake_up_adapters/redis.rb
442
+ - lib/solid_objects/web.rb
443
+ - lib/solid_objects/web/action.rb
444
+ - lib/solid_objects/web/application.rb
445
+ - lib/solid_objects/web/csrf_protection.rb
446
+ - lib/solid_objects/web/helpers.rb
447
+ - lib/solid_objects/web/paginator.rb
448
+ - lib/solid_objects/web/route.rb
449
+ - lib/solid_objects/web/router.rb
450
+ - lib/solid_objects/web/statistics.rb
427
451
  - lib/solid_objects/worker.rb
428
452
  - lib/tasks/solid_objects_tasks.rake
429
453
  - sig/generated/controllers/solid_objects/application_controller.rbs
@@ -500,6 +524,15 @@ files:
500
524
  - sig/generated/lib/solid_objects/wake_up_adapters.rbs
501
525
  - sig/generated/lib/solid_objects/wake_up_adapters/postgresql.rbs
502
526
  - sig/generated/lib/solid_objects/wake_up_adapters/redis.rbs
527
+ - sig/generated/lib/solid_objects/web.rbs
528
+ - sig/generated/lib/solid_objects/web/action.rbs
529
+ - sig/generated/lib/solid_objects/web/application.rbs
530
+ - sig/generated/lib/solid_objects/web/csrf_protection.rbs
531
+ - sig/generated/lib/solid_objects/web/helpers.rbs
532
+ - sig/generated/lib/solid_objects/web/paginator.rbs
533
+ - sig/generated/lib/solid_objects/web/route.rbs
534
+ - sig/generated/lib/solid_objects/web/router.rbs
535
+ - sig/generated/lib/solid_objects/web/statistics.rbs
503
536
  - sig/generated/lib/solid_objects/worker.rbs
504
537
  - sig/generated/models/solid_objects/broadcast.rbs
505
538
  - sig/generated/models/solid_objects/claimed_message.rbs
@@ -512,6 +545,26 @@ files:
512
545
  - sig/generated/models/solid_objects/record.rbs
513
546
  - sig/generated/models/solid_objects/reminder.rbs
514
547
  - sig/support/framework.rbs
548
+ - web/assets/javascripts/application.js
549
+ - web/assets/javascripts/charts.js
550
+ - web/assets/stylesheets/application.css
551
+ - web/views/_messages.erb
552
+ - web/views/_navigation.erb
553
+ - web/views/_paging.erb
554
+ - web/views/_status_filter.erb
555
+ - web/views/_summary.erb
556
+ - web/views/broadcasts.erb
557
+ - web/views/dashboard.erb
558
+ - web/views/dead_letter.erb
559
+ - web/views/dead_letters.erb
560
+ - web/views/effects.erb
561
+ - web/views/instance.erb
562
+ - web/views/instances.erb
563
+ - web/views/layout.erb
564
+ - web/views/mailbox.erb
565
+ - web/views/message.erb
566
+ - web/views/processes.erb
567
+ - web/views/reminders.erb
515
568
  homepage: https://solidobjects.dev
516
569
  licenses:
517
570
  - MIT