Skip to content

Add reactive ERB components - #1

Merged
cardmagic merged 4 commits into
mainfrom
agent/reactive-erb-components
Aug 7, 2026
Merged

Add reactive ERB components#1
cardmagic merged 4 commits into
mainfrom
agent/reactive-erb-components

Conversation

@cardmagic

Copy link
Copy Markdown
Owner

What changed

  • add dependency-driven actor.component(..., observes:) rendering for collections, conditionals, nested ERB, and personalized content
  • deliver durable observable invalidations over the existing single actor subscription, then render host partials through an authorized request-time Turbo Frame endpoint
  • add signed component registrations, conventional partial resolution, reconnect convergence, same-turn dependency coalescing, and monotonic stale-update rejection
  • sign the scalar observable targets rendered in each scope so component-only dependencies do not expose their serialized values to the browser
  • persist state_revision atomically with fenced actor state, message completion, and broadcast outbox rows
  • update the chat-room example, generator guidance, README, architecture, authorization, correctness, schema, realtime, roadmap, and changelog

Why

Scalar observable replacement escaped arrays and hashes as JSON, while component partials rendered only once. Rendering personalized HTML into a shared durable broadcast would cross subscriber authorization boundaries. This design keeps the database row as the committed source of truth and broadcasts invalidation metadata; each browser refreshes with its normal request cookies and is reauthorized before host ERB is rendered.

Security and correctness

  • initial component rendering, Action Cable subscription, and every HTTP refresh use distinct host authorization contexts
  • signed tokens constrain identity, dependencies, component convention, revision, and same-origin path but never grant access
  • reactive partials resolve only actors/<actor_class>/_<component> and can read only declared observables
  • personalized HTML is private, no-store and never enters an outbox row or shared Cable payload
  • rolled-back and fenced-out turns cannot advance state_revision or enqueue invalidations
  • (instance_id, state_revision) rejects older invalidations and distinguishes destroy/recreate incarnations
  • reconnect compares signed initial revision with current committed state

Migration

Adds the portable, non-null solid_objects_instances.state_revision bigint with a default of 0. Successful fenced commits advance it to the actor message sequence.

Validation

  • bundle exec rake — 205 runs, 792 assertions; Standard Ruby, RuboCop, RBS validation, Steep, and Brakeman all pass; 0 security warnings
  • SOLID_OBJECTS_DATABASE_URL=postgresql://... bundle exec rake test against PostgreSQL 18 — 205 runs, 792 assertions, 0 failures/errors/skips
  • SOLID_OBJECTS_DATABASE_URL=mysql2://... bundle exec rake test against MySQL 8.4 — 205 runs, 792 assertions, 0 failures/errors/skips
  • bundle exec ruby -Itest test/integration/example_chat_room_test.rb — 1 run, 9 assertions, 0 failures/errors
  • gem build solid_objects.gemspec --output /tmp/solid_objects-reactive-erb.gem — built solid_objects 0.3.0 successfully

Follow-up

Turbo append intents and expanded full-browser reconnect coverage remain roadmap work; scalar replacement and dependency-driven full component replacement are implemented here.

@cardmagic
cardmagic marked this pull request as ready for review August 7, 2026 01:10
@cardmagic
cardmagic marked this pull request as draft August 7, 2026 01:11
@cardmagic

Copy link
Copy Markdown
Owner Author

@greptileai

@cardmagic
cardmagic marked this pull request as ready for review August 7, 2026 01:15
@cardmagic cardmagic self-assigned this Aug 7, 2026
@greptile-apps

greptile-apps Bot commented Aug 7, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds dependency-driven reactive ERB components that refresh through an authorized request-time endpoint while retaining durable actor invalidations and revision ordering.

  • Adds signed component registrations, conventional partial rendering, and per-request authorization.
  • Adds monotonic state revisions, reconnect convergence, stale-update rejection, and dependency coalescing.
  • Updates the example application, generated configuration guidance, tests, signatures, and documentation.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
lib/solid_objects/component_renderer.rb Centralizes reactive partial authorization and rendering; the component name and declared dependencies are now authorized on both render paths.
app/controllers/solid_objects/components_controller.rb Adds the signed, request-authorized component refresh endpoint with revision validation and non-cacheable responses.
lib/solid_objects/actor_channel.rb Adds scoped scalar delivery, component invalidation handling, reconnect refreshes, and stale revision filtering.
lib/solid_objects/component_subscriptions.rb Tracks signed component dependencies and coalesces refreshes by actor incarnation and revision.
lib/solid_objects/executor.rb Advances actor state revisions within the fenced transaction used for state, completion, and outbox persistence.
lib/generators/solid_objects/templates/solid_objects.rb Replaces the previously flagged commented executable component-context example with concise prose guidance.

Reviews (2): Last reviewed commit: "Preserve component authorization" | Re-trigger Greptile

Comment thread lib/solid_objects/component_renderer.rb Outdated
Comment thread lib/generators/solid_objects/templates/solid_objects.rb Outdated
@cardmagic

Copy link
Copy Markdown
Owner Author

@greptileai

Finalize the reactive component release version, changelog, lockfile, and status language so the package and documentation describe the same artifact.
@cardmagic
cardmagic merged commit 256233f into main Aug 7, 2026
8 checks passed
@cardmagic
cardmagic deleted the agent/reactive-erb-components branch August 10, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant