ruact 0.0.12 → 0.0.13

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: 4a8e7c8ef2e275bb38c837671dca78c5c2278378e95131e8e25b2f9edbb99339
4
- data.tar.gz: ab0713c0bcc7effd8d77bb6f961bcda55e8a233e124fd0669bc1133642632687
3
+ metadata.gz: 962dae09686957b84e9e34d12809714978e95e6392265b7fd7f64a7028dd86f5
4
+ data.tar.gz: ecad09e13bcc52fe30bff4ece70e14527e0c501166d2d487625c9a92ada3a2fd
5
5
  SHA512:
6
- metadata.gz: e301dbf4d7ee972f71d16beae5f972289542ecbedc353389dcbe6afe24b50f2393baf0445ebd152ef4da1114272a0a906805beb10921afe7944a318758ed38d6
7
- data.tar.gz: b69d9e0420b5b1dd7676bfc9870592efaee6438ce6ad944c4fda0d8e3173910e9c1ac6c8165d86bed6791153f801e6b990c194c422b62e3218e6716d200f0ee4
6
+ metadata.gz: 87a00a254896d68831e62bb892932c29b0668628232757f692b22c00f1a188de0db7d2ba9600e199e6f46aa1997b73ebe7fed0e6ef193a6d4b060b7fc410b2cf
7
+ data.tar.gz: f90d5ba0da42e90e7031cff6d93ce648229655a5eea726a8572664354291aa974254f5696596a339942dedf7630506292618c48323a70cf7302c247eae7cb6b3
data/CHANGELOG.md CHANGED
@@ -7,6 +7,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.0.13] - 2026-09-27
11
+
12
+ ### Added
13
+
14
+ - **A development warning when a Turbo form gets a ruact page back.** A form on a Turbo page that posts to a ruact action is fetched by Turbo; Turbo does not show the ruact page that answers (a `422` with validation errors, say): it reloads the form's page, drops the answer or pastes the document into its own, depending on the status. In development and test ruact now logs a `[ruact]` warning naming the action, the request and the fix: `data-turbo="false"` on that form, so the browser submits it and shows the answer.
15
+
16
+ ### Fixed
17
+
18
+ - **`render :new, status: :unprocessable_entity` answered 500 on a ruact page.** The Rails idiom for a failed save rendered the template outside ruact, and its first client component raised `__ruact_component__ called outside a ruact_render flow`, with no hint of the fix. A `render` whose template is a ruact page of the same controller — `render :new`, `render "new"`, `render action:`, `render template: "posts/new"` — now goes through ruact, with its `status:`, `locals:`, `location:`, `variant:`, `locale:` and `assigns:` — when that `.html.erb` (or a locale/variant of it) is the template Rails would pick for the request, so a `.json` URL or a `format.json` branch still renders the JSON template. Every other `render` (other renderers, another folder's template, an action outside `ruact_pages`, an option ruact does not take such as wicked_pdf's `pdf:` or a stray `alert:`) is Rails' own, as before — and when that leaves a client component outside ruact, the error names the option. `ruact_render` takes `status:` too. A client component in a template Rails renders on its own now raises an error naming the component, the template and the call that renders it through ruact. The client router renders a Flight `422` in place — the errors are the page, not a failed request — and keeps the form's URL; any other failing status is still an error.
19
+
20
+ - **`respond_with` (the `responders` gem, Devise's controllers) raised `NoMethodError: private method 'redirect_to'` in a controller with `Ruact::Controller`.** ruact's `redirect_to` override was private, and `responders` calls `controller.redirect_to` from outside. It is public now, as Rails' own is — and so is the new `render` override.
21
+
22
+ - **A server-function call's validation errors were lost on `redirect_to`.** An action called from React that registers `ruact_errors(@post)` and then `redirect_to`s answers `{"$redirect": …}`; the page the runtime navigated to was documented to receive those errors, and never did, in any include order. They now ride the flash to it (a same-origin redirect; a redirect to another origin carries none).
23
+
24
+ - **Clicking from a ruact page to an ordinary Rails page did nothing.** The ruact router intercepts every same-origin link and asked for a ruact response; an ordinary Rails action answered with HTML the router could not render, so the click went nowhere — no page, no URL change, no error. Now the server tells the router, before running anything, when a route is not a ruact page, and the browser loads it normally. A form that posts to such a page is submitted by the browser the same way, so the action runs once and its response — a validation error included — is what you see. `Ruact::NavigationBoundary::Middleware` does this; remove it with `config.middleware.delete Ruact::NavigationBoundary::Middleware` if you need to.
25
+
26
+ - **Turbo and ruact stopped trampling each other.** After one round trip between a Turbo page and a ruact page, Turbo's links could go dead, a ruact page could render blank, or the address bar could show one page while the screen showed another. Every page ruact renders now carries `<meta name="turbo-visit-control" content="reload">`, so Turbo loads it in full instead of swapping it into its own document, and each document keeps its own router. It also carries `<meta name="turbo-prefetch" content="false">`: in a layout that loads Turbo 8, hovering a link on a ruact page no longer makes Turbo fetch — and run — the destination for a click it will never handle.
27
+
28
+ - **Styling from an npm component worked in development and disappeared in production.** A `"use client"` component that imports CSS — its own, or one a package ships, like a date picker's — produces a separate stylesheet that Vite builds, digest-stamps and serves. Nothing linked it. The page came back with the script tag and no `<link>`, so the component rendered unstyled: in the case that surfaced this ([#63](https://github.com/luizcg/ruact/issues/63)), a date picker collapsed into a column of overlapping numbers. Development hid it completely, because the Vite dev server injects that CSS through JavaScript.
29
+
30
+ A new `<head>` helper, `ruact_head_assets`, links those stylesheets — above your own, so your CSS loads last and wins ties. It emits nothing while the Vite dev server is running. The layout ruact now ships calls it for you, and so does the built-in shell (`config.layout = false`), which still carries none of *your* stylesheets. `rails ruact:doctor` fails when a build emits component CSS that the layout rendering your pages never links, and names that layout.
31
+
32
+ - **The generated `--shadcn` `tsconfig.json` had no types for a CSS import.** A client component importing a stylesheet for its side effect had nothing to resolve against. It now declares `vite/client`. If you keep your own `tsconfig.json`, add `"types": ["vite/client"]` to it.
33
+
34
+ ### Changed
35
+
36
+ - **Installing ruact no longer turns your whole app into ruact pages.** `rails generate ruact:install` used to add `include Ruact::Controller` to `ApplicationController`, and from then on every action with an `.html.erb` rendered through ruact — install it into an existing app to try one screen and the other eighty were converted too, Turbo Frames included. Now the install changes no controller: a page renders through ruact when its controller has `include Ruact::Controller`, and `ruact_pages only: %i[show]` (or `except:`) narrows that to some actions — an action declared there counts even when it renders another action's template. The navigation boundary reads the same declaration, so a form posting to an action left out of `ruact_pages` is submitted by the browser like any Rails form — and it is plain Rails in how it shows validation errors, too. A name in `ruact_pages only:` that is neither a method nor a template of the controller declaring it raises `Ruact::ConfigurationError` — a typo does not quietly make a page plain Rails. `rails generate ruact:scaffold` adds the include to the controllers it generates.
37
+
38
+ To make every page a ruact page, as before, run `rails generate ruact:install --app`: it puts the include on `ApplicationController` and renders through your own layout. **Apps already installed keep their include** — re-running the install says the app is in whole-app mode and how to leave it, and removes nothing. `rails ruact:doctor` now reports which mode the app is in, and in whole-app mode how many templates render through ruact.
39
+
40
+ - **New installs render ruact pages through a layout the gem ships, and no longer edit yours.** `rails generate ruact:install` used to write the React root and `ruact_js_assets` into `app/views/layouts/application.html.erb`. It now writes `config.layout = "ruact"`: ruact pages render through `layouts/ruact`, which comes with the gem and links CSRF, CSP, your client components' CSS and then the stylesheets you name in the new `config.layout_stylesheets` (`[:app]` under Propshaft 0.9+; the install writes `["application"]` on Sprockets or an older Propshaft, and `[]` with neither). Your layouts are not touched.
41
+
42
+ Because it is a named layout, it applies to every ruact page whatever a controller declares with `layout` (`layout false` included), and its `<title>` is your app's name on every page. What that layout does **not** bring is the rest of your own layout's `<head>` — favicons, fonts, analytics, meta tags other gems write — or your app's JavaScript. If a ruact page needs those, `rails generate ruact:layout` copies the layout into `app/views/layouts/ruact.html.erb`, where it is yours to change and wins over the gem's with no setting. Or set `config.layout = true` to keep rendering through your own layout, as before.
43
+
44
+ **Existing installs are not changed**: re-running the install leaves a `config.layout` you already have alone. On an app that renders through its own layout, the install now prints any of the three lines that layout is missing — `ruact_head_assets` is the new one — instead of writing them.
45
+
10
46
  ## [0.0.12] - 2026-09-09
11
47
 
12
48
  ### Added
@@ -320,7 +356,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
320
356
  - **CI matrix** — GitHub Actions: RSpec across Ruby 3.2 × 3.3 × Rails 7.0 × 7.1 × 7.2 × 8.0; RuboCop; YARD docs; memory benchmark; E2E system tests against React 19.0.0 and 19.x (Capybara + Cuprite); non-blocking React@next job with auto-issue on failure.
321
357
  - **E2E test app** — `e2e/` Rails app (no DB, in-memory Post model) with full CRUD system tests validating the complete request cycle.
322
358
 
323
- [Unreleased]: https://github.com/luizcg/ruact/compare/v0.0.12...HEAD
359
+ [Unreleased]: https://github.com/luizcg/ruact/compare/v0.0.13...HEAD
360
+ [0.0.13]: https://github.com/luizcg/ruact/releases/tag/v0.0.13
324
361
  [0.0.12]: https://github.com/luizcg/ruact/releases/tag/v0.0.12
325
362
  [0.0.11]: https://github.com/luizcg/ruact/releases/tag/v0.0.11
326
363
  [0.0.10]: https://github.com/luizcg/ruact/releases/tag/v0.0.10
data/README.md CHANGED
@@ -22,14 +22,14 @@ rails new myapp --skip-javascript && cd myapp
22
22
  # 2. Add the gem
23
23
  bundle add ruact
24
24
 
25
- # 3. Write the config, the layout wiring and an AGENTS.md — then run npm install
25
+ # 3. Write the config and an AGENTS.md (no layout of yours is edited) — then run npm install
26
26
  rails generate ruact:install
27
27
 
28
28
  # 4. Rails + Vite, one command
29
29
  bin/dev
30
30
  ```
31
31
 
32
- That is the whole install. The [Getting Started guide](https://ruact.dev/docs/getting-started) picks it up from here — first component, first scaffold, `ruact:doctor`. Already have an app? Start at step 2, then read [Progressive migration](https://ruact.dev/docs/guides/progressive-migration) — ruact renders one action at a time and leaves the rest of your views alone.
32
+ That is the whole install. The [Getting Started guide](https://ruact.dev/docs/getting-started) picks it up from here — first component, first scaffold, `ruact:doctor`. Already have an app? Start at step 2, then read [Progressive migration](https://ruact.dev/docs/guides/progressive-migration) — ruact renders only the controllers you include it in and leaves the rest of your views alone.
33
33
 
34
34
  ## How it works
35
35
 
@@ -98,7 +98,7 @@ Every item below is shipped in this gem at v0.0.11:
98
98
  - **Signed record references** — `Ruact.signed_global_id(record, for:, expires_in:)` out, `Ruact.locate_signed(token, for:)` back in; a tampered token is a `400`, not a lookup. [Docs](https://ruact.dev/docs/api/server-actions)
99
99
  - **Client-side navigation** — link interception, scroll restoration and redirect-after-POST, derived from your Rails routes. [Docs](https://ruact.dev/docs/concepts/navigation)
100
100
  - **A CRUD generator** — `rails generate ruact:scaffold Post title:string body:text` delegates the model, migration and route to Rails' own `resource` generator, then adds the ruact layer. Plain semantic HTML by default; `--shadcn` opts into the Tailwind/shadcn path. It does not run migrations — `rails db:migrate` is still yours. [Docs](https://ruact.dev/docs/api/scaffold)
101
- - **`bin/rails ruact:doctor`** — eight checks over the manifest, Vite, the layout and streaming; exits `1` when one fails. [Docs](https://ruact.dev/docs/api/ruact-doctor)
101
+ - **`bin/rails ruact:doctor`** — nine checks over the manifest, Vite, the layout, the client-component CSS and streaming; exits `1` when one fails. [Docs](https://ruact.dev/docs/api/ruact-doctor)
102
102
  - **One runtime dependency** — `nokogiri`. Rails itself is not a declared dependency of this gem.
103
103
 
104
104
  ## AI tools and coding agents
@@ -136,7 +136,7 @@ Everything lives at [ruact.dev](https://ruact.dev):
136
136
  - [Getting Started](https://ruact.dev/docs/getting-started) — from `rails new` to a rendered component
137
137
  - [Why ruact?](https://ruact.dev/docs/why-ruact) — where it sits next to Hotwire and Inertia
138
138
  - [Server functions & queries](https://ruact.dev/docs/api/server-actions) — the full request/response contract
139
- - [Progressive migration](https://ruact.dev/docs/guides/progressive-migration) — adopting it one action at a time
139
+ - [Progressive migration](https://ruact.dev/docs/guides/progressive-migration) — adopting it one controller at a time
140
140
  - [Testing](https://ruact.dev/docs/guides/testing) — render assertions on the server side
141
141
  - [Changelog](CHANGELOG.md) — also published at [ruact.dev/docs/changelog](https://ruact.dev/docs/changelog)
142
142