react_on_rails 17.0.1 → 17.1.0.rc.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 +4 -4
- data/Gemfile.development_dependencies +1 -1
- data/Gemfile.lock +15 -15
- data/docs/agent/README.md +26 -0
- data/docs/agent/doctor-fix-loop.md +25 -0
- data/docs/agent/install-and-upgrade.md +164 -0
- data/docs/agent/rsc-adoption.md +31 -0
- data/docs/agent/streaming-debug.md +57 -0
- data/lib/generators/react_on_rails/base_generator.rb +4 -4
- data/lib/generators/react_on_rails/generator_helper.rb +12 -1
- data/lib/generators/react_on_rails/install_generator.rb +59 -7
- data/lib/generators/react_on_rails/js_dependency_manager.rb +1 -1
- data/lib/generators/react_on_rails/pro_generator.rb +5 -3
- data/lib/generators/react_on_rails/pro_setup.rb +51 -19
- data/lib/generators/react_on_rails/rsc_generator.rb +18 -1
- data/lib/generators/react_on_rails/rsc_setup/client_references.rb +63 -25
- data/lib/generators/react_on_rails/rsc_setup.rb +141 -39
- data/lib/generators/react_on_rails/templates/agent_files/AGENTS.md +31 -3
- data/lib/generators/react_on_rails/templates/base/base/{Procfile.dev-static-assets → Procfile.dev-static-assets.tt} +1 -1
- data/lib/generators/react_on_rails/templates/base/base/{Procfile.dev → Procfile.dev.tt} +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt +18 -42
- data/lib/react_on_rails/agent_guardrails/templates/rsc_app_safety_check.rb +215 -0
- data/lib/react_on_rails/agent_guardrails/templates/rsc_app_safety_skill.md +71 -0
- data/lib/react_on_rails/agent_guardrails.rb +223 -0
- data/lib/react_on_rails/dev/service_checker.rb +1 -1
- data/lib/react_on_rails/doctor.rb +880 -48
- data/lib/react_on_rails/doctor_schema.rb +192 -0
- data/lib/react_on_rails/engine.rb +2 -2
- data/lib/react_on_rails/helper.rb +17 -10
- data/lib/react_on_rails/length_prefixed_parser.rb +22 -14
- data/lib/react_on_rails/lenient_json.rb +0 -0
- data/lib/react_on_rails/prerender_error.rb +38 -8
- data/lib/react_on_rails/react_component/render_options.rb +1 -1
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +168 -15
- data/lib/react_on_rails/system_checker.rb +2 -1
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/tasks/agent_guardrails.rake +21 -0
- data/rakelib/run_rspec.rake +14 -0
- data/sig/react_on_rails/prerender_error.rbs +2 -1
- data/skills/doctor-fix-loop/SKILL.md +26 -0
- data/skills/install-and-upgrade/SKILL.md +24 -0
- data/skills/rsc-adoption/SKILL.md +28 -0
- data/skills/streaming-debug/SKILL.md +53 -0
- metadata +18 -4
- data/lib/generators/react_on_rails/templates/base/base/bin/shakapacker-watch +0 -26
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7026d13c6ff6a7d80dcb8c566a11e8446036d052ec2418e47f2bcdaec6a2eed3
|
|
4
|
+
data.tar.gz: 0a1354cabb04d73d50281387151ab91c440b06955d038dd0c564cc08cc20e51e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a40e5cc18caeef6e4879a46314aa86ea6c5b48128fbf60b2e4793b1d32748b334767b4f432c8ef6e1779fa21a07d53edf00253235ced9d641b5e3b43f74db4b8
|
|
7
|
+
data.tar.gz: e3af833f783b8096f457d1ecbd4e268a7e07b61f8b39f00f48de30c0c976ad5f75f3285bf534afc71d179c73af75b55c6d640a0bf82b0ff656cadfd08ab24775
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
react_on_rails (17.0.1)
|
|
4
|
+
react_on_rails (17.1.0.rc.1)
|
|
5
5
|
addressable
|
|
6
6
|
connection_pool
|
|
7
7
|
execjs (~> 2.5)
|
|
@@ -117,7 +117,7 @@ GEM
|
|
|
117
117
|
cgi (0.5.2)
|
|
118
118
|
childprocess (5.0.0)
|
|
119
119
|
coderay (1.1.3)
|
|
120
|
-
concurrent-ruby (1.3.
|
|
120
|
+
concurrent-ruby (1.3.8)
|
|
121
121
|
connection_pool (3.0.2)
|
|
122
122
|
crass (1.0.7)
|
|
123
123
|
csv (3.3.5)
|
|
@@ -132,7 +132,7 @@ GEM
|
|
|
132
132
|
drb (2.2.3)
|
|
133
133
|
equivalent-xml (0.6.0)
|
|
134
134
|
nokogiri (>= 1.4.3)
|
|
135
|
-
erb (6.0.
|
|
135
|
+
erb (6.0.7)
|
|
136
136
|
erubi (1.13.1)
|
|
137
137
|
execjs (2.9.1)
|
|
138
138
|
ffi (1.16.3)
|
|
@@ -146,7 +146,7 @@ GEM
|
|
|
146
146
|
i18n (1.15.2)
|
|
147
147
|
concurrent-ruby (~> 1.0)
|
|
148
148
|
interception (0.5)
|
|
149
|
-
io-console (0.
|
|
149
|
+
io-console (0.9.2)
|
|
150
150
|
irb (1.18.0)
|
|
151
151
|
pp (>= 0.6.0)
|
|
152
152
|
prism (>= 1.3.0)
|
|
@@ -169,7 +169,7 @@ GEM
|
|
|
169
169
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
170
170
|
rb-inotify (~> 0.9, >= 0.9.10)
|
|
171
171
|
logger (1.7.0)
|
|
172
|
-
loofah (2.25.
|
|
172
|
+
loofah (2.25.2)
|
|
173
173
|
crass (~> 1.0.2)
|
|
174
174
|
nokogiri (>= 1.12.0)
|
|
175
175
|
mail (2.9.0)
|
|
@@ -228,16 +228,16 @@ GEM
|
|
|
228
228
|
pry-rescue (1.6.0)
|
|
229
229
|
interception (>= 0.5)
|
|
230
230
|
pry (>= 0.12.0)
|
|
231
|
-
psych (5.
|
|
231
|
+
psych (5.5.0)
|
|
232
232
|
date
|
|
233
233
|
stringio
|
|
234
234
|
public_suffix (6.0.2)
|
|
235
235
|
puma (6.6.1)
|
|
236
236
|
nio4r (~> 2.0)
|
|
237
237
|
racc (1.8.1)
|
|
238
|
-
rack (3.2.
|
|
239
|
-
rack-proxy (0.
|
|
240
|
-
rack
|
|
238
|
+
rack (3.2.7)
|
|
239
|
+
rack-proxy (1.0.1)
|
|
240
|
+
rack (>= 2.0, < 4)
|
|
241
241
|
rack-session (2.1.2)
|
|
242
242
|
base64 (>= 0.1.0)
|
|
243
243
|
rack (>= 3.0.0)
|
|
@@ -263,8 +263,8 @@ GEM
|
|
|
263
263
|
activesupport (>= 5.0.0)
|
|
264
264
|
minitest
|
|
265
265
|
nokogiri (>= 1.6)
|
|
266
|
-
rails-html-sanitizer (1.7.
|
|
267
|
-
loofah (~> 2.25)
|
|
266
|
+
rails-html-sanitizer (1.7.1)
|
|
267
|
+
loofah (~> 2.25, >= 2.25.2)
|
|
268
268
|
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
|
269
269
|
railties (7.1.6)
|
|
270
270
|
actionpack (= 7.1.6)
|
|
@@ -288,7 +288,7 @@ GEM
|
|
|
288
288
|
psych (>= 4.0.0)
|
|
289
289
|
tsort
|
|
290
290
|
regexp_parser (2.11.3)
|
|
291
|
-
reline (0.
|
|
291
|
+
reline (0.7.0)
|
|
292
292
|
io-console (~> 0.5)
|
|
293
293
|
rexml (3.4.4)
|
|
294
294
|
rspec-core (3.13.0)
|
|
@@ -331,7 +331,7 @@ GEM
|
|
|
331
331
|
rubyzip (>= 1.2.2, < 3.0)
|
|
332
332
|
websocket (~> 1.0)
|
|
333
333
|
semantic_range (3.1.1)
|
|
334
|
-
shakapacker (10.3.
|
|
334
|
+
shakapacker (10.3.2)
|
|
335
335
|
activesupport (>= 5.2)
|
|
336
336
|
package_json
|
|
337
337
|
rack-proxy (>= 0.6.1)
|
|
@@ -402,7 +402,7 @@ GEM
|
|
|
402
402
|
xpath (3.2.0)
|
|
403
403
|
nokogiri (~> 1.8)
|
|
404
404
|
yard (0.9.36)
|
|
405
|
-
zeitwerk (2.8.
|
|
405
|
+
zeitwerk (2.8.3)
|
|
406
406
|
|
|
407
407
|
PLATFORMS
|
|
408
408
|
arm64-darwin
|
|
@@ -443,7 +443,7 @@ DEPENDENCIES
|
|
|
443
443
|
sass-rails (~> 6.0)
|
|
444
444
|
sdoc
|
|
445
445
|
selenium-webdriver (= 4.9.0)
|
|
446
|
-
shakapacker (= 10.3.
|
|
446
|
+
shakapacker (= 10.3.2)
|
|
447
447
|
simplecov (~> 0.16.1)
|
|
448
448
|
spring (~> 4.0)
|
|
449
449
|
sprockets (~> 4.0)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# React on Rails bundled agent reference
|
|
2
|
+
|
|
3
|
+
These guides and skills ship with the installed React on Rails version. Read them before relying on
|
|
4
|
+
training data or hosted documentation, which may describe a different release.
|
|
5
|
+
|
|
6
|
+
| Workflow | Skill | Guide |
|
|
7
|
+
| ----------------------------------- | ------------------------------------------------------------------ | --------------------------------- |
|
|
8
|
+
| Install or upgrade | [`install-and-upgrade`](../../skills/install-and-upgrade/SKILL.md) | [Guide](./install-and-upgrade.md) |
|
|
9
|
+
| Adopt React Server Components (Pro) | [`rsc-adoption`](../../skills/rsc-adoption/SKILL.md) | [Guide](./rsc-adoption.md) |
|
|
10
|
+
| Debug streaming SSR (Pro) | [`streaming-debug`](../../skills/streaming-debug/SKILL.md) | [Guide](./streaming-debug.md) |
|
|
11
|
+
| Iterate with the doctor | [`doctor-fix-loop`](../../skills/doctor-fix-loop/SKILL.md) | [Guide](./doctor-fix-loop.md) |
|
|
12
|
+
|
|
13
|
+
The gem and npm package contain byte-identical copies. Use the installed gem directory as the
|
|
14
|
+
canonical, reliable lookup:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bundle show react_on_rails
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Read `docs/agent/README.md` and the `skills/` paths from the returned directory. An optional
|
|
21
|
+
direct-dependency path is `node_modules/react-on-rails/`, but use it only when that directory
|
|
22
|
+
exists. Do not assume it exists: Pro installations may omit the direct base npm dependency, and
|
|
23
|
+
pnpm may isolate a transitive copy.
|
|
24
|
+
|
|
25
|
+
For broader explanation after reading the installed references, use the hosted documentation:
|
|
26
|
+
https://reactonrails.com/docs/.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Doctor-driven fix loop
|
|
2
|
+
|
|
3
|
+
Use the stable JSON form for agent and CI workflows:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bin/rails react_on_rails:doctor FORMAT=json
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Standard output is one JSON document. The top-level `status`, `checks`, and `summary` describe the
|
|
10
|
+
run. Every check exposes a stable `id`, `status`, `severity`, `message`, `fix_command`, `docs_url`,
|
|
11
|
+
`remediation`, and `details` contract.
|
|
12
|
+
|
|
13
|
+
For every non-passing check, in array order:
|
|
14
|
+
|
|
15
|
+
1. Record `id` and `severity`.
|
|
16
|
+
2. Inspect `message`, `remediation.files`, and the current app state.
|
|
17
|
+
3. Use `remediation.prompt` and `remediation.expected_end_state` as bounded guidance.
|
|
18
|
+
4. Review the smallest corrective diff.
|
|
19
|
+
5. Rerun the JSON doctor and confirm the check passes without creating another failure.
|
|
20
|
+
|
|
21
|
+
Exit code `1` means at least one error remains. Warnings keep exit code `0`, so read `status` or
|
|
22
|
+
`summary.warn` when warning-free output matters. A `null` `fix_command` is expected; never infer an
|
|
23
|
+
unsafe global repair command from the check ID.
|
|
24
|
+
|
|
25
|
+
Secondary reference: https://reactonrails.com/docs/api-reference/doctor.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Install and upgrade
|
|
2
|
+
|
|
3
|
+
Use this guide for an existing Rails app. Keep app-specific choices and custom configuration intact.
|
|
4
|
+
|
|
5
|
+
## Preflight
|
|
6
|
+
|
|
7
|
+
- Record the Rails, Ruby, Node, Shakapacker, React on Rails gem, npm package, and package-manager state.
|
|
8
|
+
- Identify both Ruby and JavaScript lockfiles and start from a reviewable working tree.
|
|
9
|
+
- Keep the gem and npm package on the same React on Rails release. A Pro app must also update its Pro
|
|
10
|
+
gem and JavaScript packages together.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
Add React on Rails first so Bundler resolves a compatible Shakapacker version, then pin that resolved version when
|
|
15
|
+
promoting Shakapacker to a direct dependency.
|
|
16
|
+
Choose exactly one stack flag before running the install generator.
|
|
17
|
+
Use `--standard-only` for OSS, `--pro` for Pro, or `--rsc` for Pro with RSC.
|
|
18
|
+
Do not rely on an interactive TTY prompt; replace `<STACK_FLAG>` explicitly in every command.
|
|
19
|
+
Choose the language explicitly too: replace `<LANGUAGE_CHOICE>` with `--typescript` for TypeScript,
|
|
20
|
+
or remove that placeholder for JavaScript. TypeScript is optional; omitting its flag preserves JavaScript.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bundle add react_on_rails --strict
|
|
24
|
+
SHAKAPACKER_VERSION="$(bundle exec ruby -rreact_on_rails -e 'print ReactOnRails::PackerUtils.shakapacker_version')"
|
|
25
|
+
bundle add shakapacker --version="${SHAKAPACKER_VERSION}" --strict
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For `--pro` or `--rsc`, React on Rails Pro is free for evaluation and non-production use;
|
|
29
|
+
production use requires a subscription. Review [Pro licensing and setup](https://reactonrails.com/docs/pro/upgrading-to-pro/)
|
|
30
|
+
before proceeding.
|
|
31
|
+
|
|
32
|
+
Skip this Pro-gem preparation for `--standard-only`.
|
|
33
|
+
For `--pro` or `--rsc` only, derive the exact installed base-gem version before adding the Pro gem:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
ROR_GEM_VERSION="$(bundle exec ruby -rreact_on_rails/version -e 'print ReactOnRails::VERSION')"
|
|
37
|
+
bundle add react_on_rails_pro --version="${ROR_GEM_VERSION}" --strict
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If that exact version is an unpublished prerelease, require a matching local/path `react_on_rails_pro` gem
|
|
41
|
+
and use the same exact version instead of the registry command:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
bundle add react_on_rails_pro --path="<path-to-matching-react_on_rails_pro>" --version="${ROR_GEM_VERSION}" --strict
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Never fall back silently to a stable Pro gem.
|
|
48
|
+
For `--pro` or `--rsc` only, after either Pro source command succeeds, remove the direct base-gem declaration:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
bundle remove react_on_rails
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This cleanup removes only the direct `react_on_rails` declaration; `react_on_rails_pro` retains the matching base gem
|
|
55
|
+
transitively. Do not run this cleanup for `--standard-only`.
|
|
56
|
+
|
|
57
|
+
After the conditional Pro preparation, run the generator with the explicit stack flag:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
bundle exec rails generate react_on_rails:install <LANGUAGE_CHOICE> <STACK_FLAG>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Use the app's declared JavaScript package manager if the generator prints a manual install command.
|
|
64
|
+
Review the generated initializer, Shakapacker configuration, scripts, routes, and sample files.
|
|
65
|
+
|
|
66
|
+
## Upgrade
|
|
67
|
+
|
|
68
|
+
1. Record the installed Ruby gem version as `CURRENT_VERSION`:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
CURRENT_VERSION="$(bundle exec ruby -rreact_on_rails/version -e 'puts ReactOnRails::VERSION')"
|
|
72
|
+
printf '%s\n' "$CURRENT_VERSION"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
2. Choose and verify explicit Ruby and npm target versions before editing dependency pins. Record
|
|
76
|
+
the Ruby/tag form as `GEM_TARGET_VERSION` and the npm semver form as `NPM_TARGET_VERSION`.
|
|
77
|
+
Ruby prereleases use dot notation (for example, `17.0.0.rc.6`); npm prereleases use hyphen notation
|
|
78
|
+
(for example, `17.0.0-rc.6`). Choose both explicitly rather than deriving either from
|
|
79
|
+
`CURRENT_VERSION` or from the other target.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
GEM_TARGET_VERSION="<Ruby/tag version you selected>"
|
|
83
|
+
NPM_TARGET_VERSION="<npm semver version you selected>"
|
|
84
|
+
git ls-remote --exit-code --tags https://github.com/shakacode/react_on_rails.git \
|
|
85
|
+
"refs/tags/v${GEM_TARGET_VERSION}"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
3. Read the changelog and upgrade guidance from the immutable repository tag `v<GEM_TARGET_VERSION>`:
|
|
89
|
+
`https://github.com/shakacode/react_on_rails/tree/v<GEM_TARGET_VERSION>`. Compare the complete
|
|
90
|
+
`CURRENT_VERSION..GEM_TARGET_VERSION` release range before changing dependencies:
|
|
91
|
+
`https://github.com/shakacode/react_on_rails/compare/v<CURRENT_VERSION>...v<GEM_TARGET_VERSION>`.
|
|
92
|
+
|
|
93
|
+
## JavaScript target matrix
|
|
94
|
+
|
|
95
|
+
Use exactly the row matching the detected stack. Verify every relevant package version before
|
|
96
|
+
pinning it; checking only the base package is insufficient. Use the app's declared package manager's
|
|
97
|
+
registry-inspection command for every exact package spec below. Do not assume pnpm, npm, Yarn, or Bun
|
|
98
|
+
is available merely because another package manager is installed.
|
|
99
|
+
|
|
100
|
+
- **OSS (`--standard-only`)**: pin and verify `react-on-rails@${NPM_TARGET_VERSION}`.
|
|
101
|
+
|
|
102
|
+
- **Pro (all renderers)**: pin and verify `react-on-rails-pro@${NPM_TARGET_VERSION}`. Also pin and verify
|
|
103
|
+
`react-on-rails-pro-node-renderer@${NPM_TARGET_VERSION}` only when the app uses the standalone NodeRenderer.
|
|
104
|
+
Do not add a direct `react-on-rails` dependency to Pro or RSC apps.
|
|
105
|
+
|
|
106
|
+
- **RSC (`--rsc`)**: follow the Pro rule, including its conditional standalone NodeRenderer package
|
|
107
|
+
and prohibition on a direct base dependency. Select `RSC_TARGET_VERSION` independently from the
|
|
108
|
+
target release guidance or the target tag's
|
|
109
|
+
`ReactOnRails::Generators::JsDependencyManager::RSC_PACKAGE_VERSION_PIN`:
|
|
110
|
+
`https://github.com/shakacode/react_on_rails/blob/v<GEM_TARGET_VERSION>/react_on_rails/lib/generators/react_on_rails/js_dependency_manager.rb`.
|
|
111
|
+
Never derive `RSC_TARGET_VERSION` from `NPM_TARGET_VERSION`. Pin and verify the exact
|
|
112
|
+
`react-on-rails-rsc@${RSC_TARGET_VERSION}` release.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
RSC_TARGET_VERSION="<exact RSC pin from target guidance>"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
4. Pin Ruby gems with `GEM_TARGET_VERSION` and regenerate the Bundler lockfile.
|
|
119
|
+
Apply exactly the matching JavaScript matrix row with the app's declared package manager, pin each
|
|
120
|
+
package to the verified exact version, and regenerate the JavaScript lockfile.
|
|
121
|
+
5. Detect the app's existing stack and current generator choices from its dependencies and
|
|
122
|
+
configuration. Use the one preserving mapping that matches the existing stack:
|
|
123
|
+
- Use `--standard-only` for an existing OSS stack.
|
|
124
|
+
- Use `--pro` only for an existing Pro + NodeRenderer stack.
|
|
125
|
+
- Use `--rsc` for an existing RSC stack.
|
|
126
|
+
|
|
127
|
+
Pro + ExecJS has no preserving install-generator flag.
|
|
128
|
+
For that stack, skip both generator preview and apply steps; upgrade dependencies and configuration manually.
|
|
129
|
+
Preserve the ExecJS renderer setup. For the three preserving mappings, preserve the current stack.
|
|
130
|
+
Preserve every other current generator choice, such as TypeScript, Redux, or generated
|
|
131
|
+
test-framework choices.
|
|
132
|
+
|
|
133
|
+
6. For a stack with a preserving mapping, first rerun the generator as a preview, substituting the
|
|
134
|
+
selected stack flag and the app's other current choices:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
bundle exec rails generate react_on_rails:install --pretend <STACK_FLAG> <OTHER_CURRENT_CHOICES>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`--pretend` omits dependency installation and script effects; it is not a complete mutation audit.
|
|
141
|
+
Review the complete preview without overwriting app-owned configuration. Never prescribe or run a
|
|
142
|
+
bare, non-TTY generator rerun.
|
|
143
|
+
|
|
144
|
+
7. Only for a stack with a preserving mapping, and only after reviewing and accepting the preview,
|
|
145
|
+
apply the same choices without `--pretend` in a clean branch or worktree:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
bundle exec rails generate react_on_rails:install <STACK_FLAG> <OTHER_CURRENT_CHOICES>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Before accepting any generated change, audit `package.json` and the JavaScript lockfile against
|
|
152
|
+
their pre-run state. The apply step installs the generator's current dependency defaults even
|
|
153
|
+
though `--pretend` skipped them; preserve intentional app pins and reject unintended upgrades.
|
|
154
|
+
|
|
155
|
+
8. Run the doctor loop, compile assets, and run focused application tests.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
bin/rails react_on_rails:doctor FORMAT=json
|
|
159
|
+
bundle exec rails shakapacker:compile
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Secondary references:
|
|
163
|
+
https://reactonrails.com/docs/getting-started/existing-rails-app and
|
|
164
|
+
https://reactonrails.com/docs/upgrading/upgrading-react-on-rails.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# React Server Components adoption (Pro)
|
|
2
|
+
|
|
3
|
+
React Server Components require React on Rails Pro. Use the generator and installed package contracts;
|
|
4
|
+
do not reconstruct the RSC build or renderer protocol from memory.
|
|
5
|
+
|
|
6
|
+
## Adoption sequence
|
|
7
|
+
|
|
8
|
+
1. Confirm the Pro gem/npm packages, Node renderer, React, React DOM, and RSC package are compatible.
|
|
9
|
+
2. Preserve the app's language when running the generator: use
|
|
10
|
+
`bundle exec rails generate react_on_rails:rsc --typescript` for a TypeScript app and
|
|
11
|
+
`bundle exec rails generate react_on_rails:rsc` for a JavaScript app. Review the generated client,
|
|
12
|
+
server, and RSC bundle configuration.
|
|
13
|
+
3. Move one leaf at a time. The `'use client'` directive marks the server-to-client boundary, not
|
|
14
|
+
every module that will execute on the client. Modules imported below that boundary remain client code
|
|
15
|
+
even when they lack the directive; place it only where a subtree needs browser APIs, state, effects,
|
|
16
|
+
or event handlers.
|
|
17
|
+
4. Keep `.client.` and `.server.` suffixes conceptually separate: they select bundle placement and do
|
|
18
|
+
not classify React Server Components.
|
|
19
|
+
5. Keep Rails-owned data and security decisions in Rails. Supply data through props or async props;
|
|
20
|
+
server components do not gain in-process access to Rails models, sessions, or cookies.
|
|
21
|
+
6. Install the app safety guardrails and review the generated skill and advisory hook:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bundle exec rake react_on_rails:install_rsc_agent_guardrails
|
|
25
|
+
bin/rails react_on_rails:doctor FORMAT=json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Before completion, protect any RSC payload route, keep the Node renderer private, avoid sensitive
|
|
29
|
+
logged props or URLs, build all three bundles, and exercise navigation and hydration in a browser.
|
|
30
|
+
|
|
31
|
+
Secondary reference: https://reactonrails.com/docs/pro/react-server-components.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Streaming SSR debugging (Pro)
|
|
2
|
+
|
|
3
|
+
Streaming requires React on Rails Pro and the Node renderer. First determine whether the selected
|
|
4
|
+
helper is progressive or intentionally buffered.
|
|
5
|
+
|
|
6
|
+
## Debug in boundary order
|
|
7
|
+
|
|
8
|
+
1. Run `bin/rails react_on_rails:doctor FORMAT=json` and resolve configuration or dependency errors.
|
|
9
|
+
2. Identify the exact helper before applying streaming prerequisites.
|
|
10
|
+
|
|
11
|
+
## Progressive helpers
|
|
12
|
+
|
|
13
|
+
For `stream_react_component`, `cached_stream_react_component`, and
|
|
14
|
+
`stream_react_component_with_async_props`:
|
|
15
|
+
|
|
16
|
+
1. Confirm the controller includes `ReactOnRailsPro::Stream`, the action enters the view through
|
|
17
|
+
`stream_view_containing_react_components` instead of ordinary `render`, and the Node renderer
|
|
18
|
+
is reachable.
|
|
19
|
+
2. When Suspense content should reveal progressively, confirm the boundary's child actually suspends.
|
|
20
|
+
3. For `stream_react_component_with_async_props` only, confirm
|
|
21
|
+
`ReactOnRailsPro.configuration.enable_rsc_support` is enabled by setting
|
|
22
|
+
`config.enable_rsc_support = true` in the Pro initializer.
|
|
23
|
+
This is not a prerequisite for `stream_react_component` or `cached_stream_react_component`.
|
|
24
|
+
4. For async props, start slow work inside the streaming block, emit only JSON-serializable values,
|
|
25
|
+
and emit or reject every prop the renderer requests.
|
|
26
|
+
|
|
27
|
+
## Buffered helpers
|
|
28
|
+
|
|
29
|
+
For `buffered_stream_react_component`, `cached_buffered_stream_react_component`, and
|
|
30
|
+
`cached_static_rsc_component`:
|
|
31
|
+
|
|
32
|
+
1. Confirm the Node renderer is reachable and inspect the complete buffered result.
|
|
33
|
+
2. These helpers do not require the streaming controller wrapper: they do not require
|
|
34
|
+
`ReactOnRailsPro::Stream`, `stream_view_containing_react_components`, or a suspending boundary.
|
|
35
|
+
3. For `cached_static_rsc_component`, set `config.enable_rsc_support = true`; disabling RSC support
|
|
36
|
+
omits the RSC payload generation that gives this helper its static-RSC behavior.
|
|
37
|
+
This setting is not a prerequisite for `buffered_stream_react_component` or
|
|
38
|
+
`cached_buffered_stream_react_component`.
|
|
39
|
+
4. Expect the browser to receive the page only after the renderer has produced the complete result;
|
|
40
|
+
early shell flush and progressive Suspense reveal are not buffered-helper behavior.
|
|
41
|
+
|
|
42
|
+
## Debug either path
|
|
43
|
+
|
|
44
|
+
Probe the origin with buffering disabled in the client, then compare the same route through each
|
|
45
|
+
reverse proxy or CDN. Inspect response headers, chunk arrival, compression, Rails logs, Node
|
|
46
|
+
renderer logs, and browser timing marks.
|
|
47
|
+
|
|
48
|
+
A useful transport probe is:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
curl --no-buffer --dump-header - https://your-app.example/streaming-route
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
If the origin streams but the public route buffers, fix the proxy/CDN boundary. If neither streams,
|
|
55
|
+
reduce to one Suspense boundary and one known-slow value before changing application architecture.
|
|
56
|
+
|
|
57
|
+
Secondary reference: https://reactonrails.com/docs/pro/streaming-ssr.
|
|
@@ -251,9 +251,7 @@ module ReactOnRails
|
|
|
251
251
|
ensure_new_app_root_route_initialized
|
|
252
252
|
|
|
253
253
|
base_path = "base/base/"
|
|
254
|
-
base_files = %w[Procfile.dev
|
|
255
|
-
Procfile.dev-static-assets
|
|
256
|
-
Procfile.dev-prod-assets
|
|
254
|
+
base_files = %w[Procfile.dev-prod-assets
|
|
257
255
|
.dev-services.yml.example
|
|
258
256
|
.env.example
|
|
259
257
|
bin/shakapacker-precompile-hook]
|
|
@@ -262,7 +260,9 @@ module ReactOnRails
|
|
|
262
260
|
# Exception: Redux still needs the HelloWorld controller even with RSC
|
|
263
261
|
base_files << "app/controllers/hello_world_controller.rb" unless use_rsc? && !options.redux?
|
|
264
262
|
base_files << "app/controllers/home_controller.rb" if generate_new_app_home_page?
|
|
265
|
-
base_templates = %w[
|
|
263
|
+
base_templates = %w[Procfile.dev
|
|
264
|
+
Procfile.dev-static-assets
|
|
265
|
+
config/initializers/react_on_rails.rb]
|
|
266
266
|
base_files.each { |file| copy_file("#{base_path}#{file}", file) }
|
|
267
267
|
copy_react_on_rails_default_layout(base_path)
|
|
268
268
|
warn_existing_hello_world_tailwind_layout
|
|
@@ -85,7 +85,7 @@ module GeneratorHelper
|
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
def add_documentation_reference(message, source)
|
|
88
|
-
"#{message}
|
|
88
|
+
"#{message}\n#{source}"
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
def print_generator_messages
|
|
@@ -492,6 +492,17 @@ module GeneratorHelper
|
|
|
492
492
|
nil
|
|
493
493
|
end
|
|
494
494
|
|
|
495
|
+
# Prefer Shakapacker's optional watcher binstub when the application has an executable copy. Older
|
|
496
|
+
# supported Shakapacker installations can still run watch mode through the required
|
|
497
|
+
# bin/shakapacker binstub, so React on Rails does not need to vendor a fallback watcher.
|
|
498
|
+
def shakapacker_watch_command
|
|
499
|
+
watch_binstub = File.join(destination_root, "bin/shakapacker-watch")
|
|
500
|
+
watch_binstub_available = File.file?(watch_binstub) && File.executable?(watch_binstub)
|
|
501
|
+
executable = watch_binstub_available ? "bin/shakapacker-watch" : "bin/shakapacker"
|
|
502
|
+
|
|
503
|
+
"#{executable} --watch"
|
|
504
|
+
end
|
|
505
|
+
|
|
495
506
|
# Check if Shakapacker 9.0 or higher is available
|
|
496
507
|
# Returns true if Shakapacker >= 9.0, false otherwise
|
|
497
508
|
#
|
|
@@ -86,16 +86,22 @@ module ReactOnRails
|
|
|
86
86
|
desc: "Write AI-agent guidance files (AGENTS.md + editor pointers). Default: true"
|
|
87
87
|
|
|
88
88
|
# --pro
|
|
89
|
+
# No static default: prompt suppression needs to distinguish an omitted flag from --no-pro.
|
|
89
90
|
class_option :pro,
|
|
90
91
|
type: :boolean,
|
|
91
|
-
|
|
92
|
-
desc: "Install React on Rails Pro with Node Renderer. Default: false"
|
|
92
|
+
desc: "Install React on Rails Pro with Node Renderer"
|
|
93
93
|
|
|
94
94
|
# --rsc
|
|
95
|
+
# No static default: prompt suppression needs to distinguish an omitted flag from --no-rsc.
|
|
95
96
|
class_option :rsc,
|
|
97
|
+
type: :boolean,
|
|
98
|
+
desc: "Install React Server Components support (includes Pro)"
|
|
99
|
+
|
|
100
|
+
# --standard-only
|
|
101
|
+
class_option :standard_only,
|
|
96
102
|
type: :boolean,
|
|
97
103
|
default: false,
|
|
98
|
-
desc: "Install
|
|
104
|
+
desc: "Install only the open-source package; cannot be combined with --pro or --rsc"
|
|
99
105
|
|
|
100
106
|
# Hidden option: allows tests (and advanced users) to signal that Shakapacker
|
|
101
107
|
# was just installed, triggering force-overwrite of shakapacker.yml with RoR's template.
|
|
@@ -196,6 +202,7 @@ module ReactOnRails
|
|
|
196
202
|
# This is inherited by all invoked generators and persists through Rails initialization
|
|
197
203
|
# See lib/react_on_rails/engine.rb for the validation skip logic
|
|
198
204
|
ENV["REACT_ON_RAILS_SKIP_VALIDATION"] = "true"
|
|
205
|
+
prompt_for_pro_features_if_applicable
|
|
199
206
|
|
|
200
207
|
if installation_prerequisites_met? || options.ignore_warnings?
|
|
201
208
|
invoke_generators
|
|
@@ -230,6 +237,40 @@ module ReactOnRails
|
|
|
230
237
|
|
|
231
238
|
private
|
|
232
239
|
|
|
240
|
+
def use_pro?
|
|
241
|
+
return @interactive_pro_selection if defined?(@interactive_pro_selection)
|
|
242
|
+
|
|
243
|
+
!!super
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def prompt_for_pro_features_if_applicable
|
|
247
|
+
validate_product_stack_choice!
|
|
248
|
+
return if options.new_app? || explicit_product_stack_choice? || !interactive_install_session?
|
|
249
|
+
|
|
250
|
+
say "React on Rails Pro is free for evaluation; production use requires a subscription."
|
|
251
|
+
say "Learn more: https://reactonrails.com/docs/pro/upgrading-to-pro/"
|
|
252
|
+
answer = ask(
|
|
253
|
+
"Enable React on Rails Pro features (Node Renderer and streaming SSR; RSC available separately)? [Y/n]",
|
|
254
|
+
:cyan
|
|
255
|
+
)
|
|
256
|
+
normalized_answer = answer.to_s.strip
|
|
257
|
+
@interactive_pro_selection = normalized_answer.empty? || normalized_answer.match?(/\A(?:y|yes)\z/i)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def explicit_product_stack_choice?
|
|
261
|
+
options.key?(:pro) || options.key?(:rsc) || options.standard_only?
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def interactive_install_session?
|
|
265
|
+
!ReactOnRails::GitUtils.truthy_env?(ENV.fetch("CI", nil)) && $stdin.tty? && $stdout.tty?
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def validate_product_stack_choice!
|
|
269
|
+
return unless options.standard_only? && (options.pro? || options.rsc?)
|
|
270
|
+
|
|
271
|
+
raise Thor::Error, "--standard-only cannot be combined with --pro or --rsc"
|
|
272
|
+
end
|
|
273
|
+
|
|
233
274
|
# Fresh-install context: default to Rspack (when Shakapacker supports it) unless the
|
|
234
275
|
# app already declares a bundler. See GeneratorHelper#fresh_install_rspack_default.
|
|
235
276
|
# NOTE: BaseGenerator#rspack_bundler_default is an intentional twin of this override
|
|
@@ -866,8 +907,12 @@ module ReactOnRails
|
|
|
866
907
|
end
|
|
867
908
|
|
|
868
909
|
def product_stack_install_flag
|
|
869
|
-
return "--rsc" if
|
|
870
|
-
return "--pro" if
|
|
910
|
+
return "--rsc" if use_rsc?
|
|
911
|
+
return "--pro" if use_pro?
|
|
912
|
+
return "--standard-only" if options.standard_only?
|
|
913
|
+
return "--no-rsc" if options.key?(:rsc)
|
|
914
|
+
return "--no-pro" if options.key?(:pro)
|
|
915
|
+
return "--standard-only" if defined?(@interactive_pro_selection)
|
|
871
916
|
|
|
872
917
|
nil
|
|
873
918
|
end
|
|
@@ -988,7 +1033,13 @@ module ReactOnRails
|
|
|
988
1033
|
say "📝 Adding Shakapacker to Gemfile...", :yellow
|
|
989
1034
|
# Use with_unbundled_env to prevent inheriting BUNDLE_GEMFILE from parent process
|
|
990
1035
|
# See: https://github.com/shakacode/react_on_rails/issues/2287
|
|
991
|
-
|
|
1036
|
+
# Pin the version already resolved through react_on_rails. Without an explicit
|
|
1037
|
+
# version, `bundle add --strict` can prefer an older globally installed gem and
|
|
1038
|
+
# downgrade the target app's lockfile.
|
|
1039
|
+
shakapacker_version = ReactOnRails::PackerUtils.shakapacker_version
|
|
1040
|
+
success = Bundler.with_unbundled_env do
|
|
1041
|
+
system("bundle", "add", "shakapacker", "--version", shakapacker_version, "--strict")
|
|
1042
|
+
end
|
|
992
1043
|
return true if success
|
|
993
1044
|
|
|
994
1045
|
handle_shakapacker_gemfile_error
|
|
@@ -1118,6 +1169,7 @@ module ReactOnRails
|
|
|
1118
1169
|
end
|
|
1119
1170
|
|
|
1120
1171
|
def handle_shakapacker_gemfile_error
|
|
1172
|
+
shakapacker_version = ReactOnRails::PackerUtils.shakapacker_version
|
|
1121
1173
|
error = <<~MSG.strip
|
|
1122
1174
|
🚫 Failed to add Shakapacker to your Gemfile.
|
|
1123
1175
|
|
|
@@ -1127,7 +1179,7 @@ module ReactOnRails
|
|
|
1127
1179
|
• Gemfile permissions
|
|
1128
1180
|
|
|
1129
1181
|
Please try manually:
|
|
1130
|
-
bundle add shakapacker --strict
|
|
1182
|
+
bundle add shakapacker --version #{shakapacker_version} --strict
|
|
1131
1183
|
|
|
1132
1184
|
#{recovery_working_tree_note}
|
|
1133
1185
|
Then re-run: #{recovery_install_command}
|
|
@@ -177,7 +177,7 @@ module ReactOnRails
|
|
|
177
177
|
end
|
|
178
178
|
|
|
179
179
|
def add_js_dependencies
|
|
180
|
-
using_pro = respond_to?(:use_pro
|
|
180
|
+
using_pro = respond_to?(:use_pro?, true) && use_pro?
|
|
181
181
|
using_rsc = respond_to?(:use_rsc?) && use_rsc?
|
|
182
182
|
# Pro package includes react-on-rails, so skip base package when using Pro
|
|
183
183
|
add_react_on_rails_package unless using_pro
|
|
@@ -40,9 +40,11 @@ module ReactOnRails
|
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
setup_pro
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
unless options[:invoked_by_install]
|
|
44
|
+
add_pro_npm_dependencies
|
|
45
|
+
update_imports_to_pro_package
|
|
46
|
+
print_success_message
|
|
47
|
+
end
|
|
46
48
|
else
|
|
47
49
|
GeneratorMessages.add_error(<<~MSG.strip)
|
|
48
50
|
🚫 React on Rails Pro generator prerequisites not met!
|