ruact 0.0.5 → 0.0.6

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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +54 -2
  3. data/.rubocop_todo.yml +3 -115
  4. data/CHANGELOG.md +67 -18
  5. data/bench/server_functions_dispatch_bench.rb +109 -142
  6. data/bench/server_functions_dispatch_bench.results.md +29 -0
  7. data/docs/internal/decisions/server-functions-api.md +402 -0
  8. data/lib/generators/ruact/install/install_generator.rb +310 -25
  9. data/lib/generators/ruact/install/templates/Procfile.dev.tt +2 -0
  10. data/lib/generators/ruact/install/templates/dev.tt +16 -0
  11. data/lib/generators/ruact/install/templates/package.json.tt +17 -0
  12. data/lib/generators/ruact/install/templates/vite.config.js.tt +3 -1
  13. data/lib/generators/ruact/scaffold/scaffold_attribute.rb +114 -0
  14. data/lib/generators/ruact/scaffold/scaffold_form_helpers.rb +114 -0
  15. data/lib/generators/ruact/scaffold/scaffold_generator.rb +491 -0
  16. data/lib/generators/ruact/scaffold/scaffold_shadcn_preflight.rb +229 -0
  17. data/lib/generators/ruact/scaffold/templates/components/DeleteDialog.tsx.tt +104 -0
  18. data/lib/generators/ruact/scaffold/templates/components/Form.tsx.tt +212 -0
  19. data/lib/generators/ruact/scaffold/templates/components/List.tsx.tt +338 -0
  20. data/lib/generators/ruact/scaffold/templates/components/agnostic/DeleteDialog.tsx.tt +92 -0
  21. data/lib/generators/ruact/scaffold/templates/components/agnostic/Form.tsx.tt +174 -0
  22. data/lib/generators/ruact/scaffold/templates/components/agnostic/List.tsx.tt +253 -0
  23. data/lib/generators/ruact/scaffold/templates/controller.rb.tt +130 -0
  24. data/lib/generators/ruact/scaffold/templates/queries/application_query.rb.tt +13 -0
  25. data/lib/generators/ruact/scaffold/templates/queries/query.rb.tt +59 -0
  26. data/lib/generators/ruact/scaffold/templates/request_spec.rb.tt +77 -0
  27. data/lib/generators/ruact/scaffold/templates/views/edit.html.erb.tt +7 -0
  28. data/lib/generators/ruact/scaffold/templates/views/index.html.erb.tt +6 -0
  29. data/lib/generators/ruact/scaffold/templates/views/new.html.erb.tt +5 -0
  30. data/lib/generators/ruact/scaffold/templates/views/show.html.erb.tt +16 -0
  31. data/lib/ruact/client_manifest.rb +37 -36
  32. data/lib/ruact/component_contract.rb +115 -0
  33. data/lib/ruact/configuration.rb +80 -28
  34. data/lib/ruact/controller.rb +69 -421
  35. data/lib/ruact/doctor.rb +133 -4
  36. data/lib/ruact/erb_preprocessor.rb +65 -12
  37. data/lib/ruact/erb_preprocessor_hook.rb +4 -1
  38. data/lib/ruact/errors.rb +30 -44
  39. data/lib/ruact/html_converter.rb +22 -1
  40. data/lib/ruact/railtie.rb +56 -200
  41. data/lib/ruact/server.rb +28 -6
  42. data/lib/ruact/server_functions/codegen.rb +49 -188
  43. data/lib/ruact/server_functions/codegen_v2.rb +23 -6
  44. data/lib/ruact/server_functions/codegen_v2_query_params.rb +140 -0
  45. data/lib/ruact/server_functions/error_payload.rb +1 -1
  46. data/lib/ruact/server_functions/error_rendering.rb +22 -29
  47. data/lib/ruact/server_functions/name_bridge.rb +14 -16
  48. data/lib/ruact/server_functions/query_source.rb +35 -8
  49. data/lib/ruact/server_functions/route_source.rb +3 -4
  50. data/lib/ruact/server_functions/snapshot.rb +12 -139
  51. data/lib/ruact/server_functions/validation_errors.rb +70 -0
  52. data/lib/ruact/server_functions.rb +21 -25
  53. data/lib/ruact/signed_references.rb +162 -0
  54. data/lib/ruact/string_distance.rb +72 -0
  55. data/lib/ruact/validation_errors_collector.rb +139 -0
  56. data/lib/ruact/version.rb +1 -1
  57. data/lib/ruact/view_helper.rb +102 -0
  58. data/lib/ruact.rb +19 -19
  59. data/lib/tasks/ruact.rake +10 -53
  60. data/spec/fixtures/story_7_9_views/controller_request_spec_support/errors_demo/new.html.erb +3 -0
  61. data/spec/ruact/client_manifest_spec.rb +36 -0
  62. data/spec/ruact/component_contract_spec.rb +119 -0
  63. data/spec/ruact/configuration_spec.rb +51 -34
  64. data/spec/ruact/controller_request_spec.rb +264 -0
  65. data/spec/ruact/controller_spec.rb +63 -326
  66. data/spec/ruact/doctor_spec.rb +201 -0
  67. data/spec/ruact/erb_preprocessor_hook_spec.rb +4 -1
  68. data/spec/ruact/erb_preprocessor_spec.rb +127 -0
  69. data/spec/ruact/errors_spec.rb +0 -45
  70. data/spec/ruact/html_converter_spec.rb +50 -0
  71. data/spec/ruact/install_generator_spec.rb +591 -4
  72. data/spec/ruact/query_request_spec.rb +109 -1
  73. data/spec/ruact/scaffold_generator_spec.rb +1835 -0
  74. data/spec/ruact/server_bucket_request_spec.rb +142 -0
  75. data/spec/ruact/server_function_name_spec.rb +1 -1
  76. data/spec/ruact/server_functions/codegen_spec.rb +158 -269
  77. data/spec/ruact/server_functions/name_bridge_spec.rb +9 -9
  78. data/spec/ruact/server_functions/query_source_spec.rb +51 -0
  79. data/spec/ruact/server_functions/railtie_integration_spec.rb +71 -268
  80. data/spec/ruact/server_functions/rake_spec.rb +29 -29
  81. data/spec/ruact/server_functions/snapshot_spec.rb +53 -213
  82. data/spec/ruact/server_rescue_request_spec.rb +6 -6
  83. data/spec/ruact/server_spec.rb +8 -9
  84. data/spec/ruact/signed_references_spec.rb +164 -0
  85. data/spec/ruact/string_distance_spec.rb +38 -0
  86. data/spec/ruact/validation_errors_spec.rb +116 -0
  87. data/spec/ruact/view_helper_spec.rb +79 -0
  88. data/spec/spec_helper.rb +0 -5
  89. data/vendor/javascript/ruact-server-functions-runtime/index.d.ts +40 -45
  90. data/vendor/javascript/ruact-server-functions-runtime/index.js +42 -98
  91. data/vendor/javascript/ruact-server-functions-runtime/index.test.mjs +72 -75
  92. data/vendor/javascript/ruact-server-functions-runtime/package.json +1 -1
  93. data/vendor/javascript/vite-plugin-ruact/bootstrap.test.mjs +96 -0
  94. data/vendor/javascript/vite-plugin-ruact/index.js +353 -7
  95. data/vendor/javascript/vite-plugin-ruact/manifest-contract.test.mjs +182 -0
  96. data/vendor/javascript/vite-plugin-ruact/package-lock.json +16 -0
  97. data/vendor/javascript/vite-plugin-ruact/package.json +3 -1
  98. data/vendor/javascript/vite-plugin-ruact/registry.test.mjs +199 -0
  99. data/vendor/javascript/vite-plugin-ruact/runtime/bootstrap.jsx +68 -0
  100. data/vendor/javascript/vite-plugin-ruact/runtime/flight-client.js +235 -0
  101. data/vendor/javascript/vite-plugin-ruact/runtime/ruact-router.js +473 -0
  102. data/vendor/javascript/vite-plugin-ruact/server-functions-codegen.mjs +114 -139
  103. data/vendor/javascript/vite-plugin-ruact/server-functions-codegen.test.mjs +199 -262
  104. data/vendor/javascript/vite-plugin-ruact/tsconfig.json +18 -0
  105. data/vendor/javascript/vite-plugin-ruact/tsconfig.scaffold-agnostic.json +18 -0
  106. data/vendor/javascript/vite-plugin-ruact/tsconfig.scaffold.json +20 -0
  107. data/vendor/javascript/vite-plugin-ruact/type-tests/emitted-module.test-d.ts +23 -0
  108. data/vendor/javascript/vite-plugin-ruact/type-tests/scaffold/PostDeleteDialog.tsx +90 -0
  109. data/vendor/javascript/vite-plugin-ruact/type-tests/scaffold/PostForm.tsx +238 -0
  110. data/vendor/javascript/vite-plugin-ruact/type-tests/scaffold/PostList.tsx +339 -0
  111. data/vendor/javascript/vite-plugin-ruact/type-tests/scaffold/agnostic/PostDeleteDialog.tsx +85 -0
  112. data/vendor/javascript/vite-plugin-ruact/type-tests/scaffold/agnostic/PostForm.tsx +216 -0
  113. data/vendor/javascript/vite-plugin-ruact/type-tests/scaffold/agnostic/PostList.tsx +269 -0
  114. data/vendor/javascript/vite-plugin-ruact/type-tests/scaffold/agnostic/ambient.d.ts +78 -0
  115. data/vendor/javascript/vite-plugin-ruact/type-tests/scaffold/ambient.d.ts +166 -0
  116. data/vendor/javascript/vite-plugin-ruact/type-tests/typed-query.test-d.ts +48 -0
  117. data/vendor/javascript/vite-plugin-ruact/type-tests/usequery.test-d.ts +26 -0
  118. metadata +55 -15
  119. data/lib/generators/ruact/install/templates/application.jsx.tt +0 -51
  120. data/lib/ruact/server_action.rb +0 -131
  121. data/lib/ruact/server_functions/endpoint_controller.rb +0 -237
  122. data/lib/ruact/server_functions/registry.rb +0 -148
  123. data/lib/ruact/server_functions/registry_entry.rb +0 -26
  124. data/lib/ruact/server_functions/standalone_context.rb +0 -103
  125. data/lib/ruact/server_functions/standalone_dispatcher.rb +0 -178
  126. data/spec/ruact/server_functions/csrf_request_spec.rb +0 -380
  127. data/spec/ruact/server_functions/dispatch_request_spec.rb +0 -819
  128. data/spec/ruact/server_functions/registry_spec.rb +0 -199
  129. data/spec/ruact/server_functions/standalone_action_spec.rb +0 -224
  130. data/spec/ruact/server_functions/standalone_context_spec.rb +0 -142
  131. data/spec/ruact/server_functions/standalone_dispatcher_spec.rb +0 -273
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f8e264e2e404e5257d0fe7457cef545f4104288dc16db01e1c8e5762d361f99
4
- data.tar.gz: 4a2ed748edb281b7d8bb0c20ce5e404db6ce7872f82c8db1545349ab709677d3
3
+ metadata.gz: 4ecde11a9eeeaa534f73c9aba3a1c15a1bb44bbe1035467dad11b6f8517085aa
4
+ data.tar.gz: 7b3077daa2fe5cef2189b40c575df223cc960b49e8ace3ce5cebf8b61afd9e29
5
5
  SHA512:
6
- metadata.gz: 36eb5942d50d3761874bd912a9cfae5ad3538500b8e08a79b196310db8db66bc86fa8a6fc78262c8a2e73ba659feaa1dd821c344fe89ecbddf247c2e05924153
7
- data.tar.gz: f8902075c57bb47e42f404d43a864829719bddc4f497371097f0c1576ef1565312b45e628f1d7a3e9a3811db497e1aa8325f8e935da4e7b4941ae2bdc468d72e
6
+ metadata.gz: 2696f4a816b237e124465604bc04a2d5a54804601d413bf907429376efb8b72d17ff876f013fb4491df47c4b231a696f7213c8e431e5924f4a504e7d2b7a1214
7
+ data.tar.gz: e1cf6a62a6e0d4e5d061b4dae97fe71d47df9137db0a3cc1581cb1056282a0b757a69eff7d1a7981ae3a419ee9d79be938871cb1f636d612e2a6affd026a809f
@@ -151,6 +151,40 @@ jobs:
151
151
  - name: Validate YARD docs
152
152
  run: bundle exec yard --fail-on-warning
153
153
 
154
+ js:
155
+ # Required status check — the bundled Vite plugin's JS suite. Runs the
156
+ # vitest codegen tests (incl. the Ruby↔JS byte-parity cases, which shell out
157
+ # to `ruby` — hence Ruby is set up alongside Node) and, Story 13.4, the
158
+ # `tsc --noEmit` type-level test that proves the emitted typed-query accessor
159
+ # signatures are enforced at compile time (FR99 / AC6).
160
+ name: JS (vite-plugin codegen + typecheck)
161
+ runs-on: ubuntu-latest
162
+ defaults:
163
+ run:
164
+ working-directory: vendor/javascript/vite-plugin-ruact
165
+ steps:
166
+ - uses: actions/checkout@v5
167
+ - uses: ruby/setup-ruby@v1
168
+ with:
169
+ ruby-version: "3.3"
170
+ bundler-cache: false
171
+ - uses: actions/setup-node@v4
172
+ with:
173
+ node-version: "20"
174
+ - name: Install JS deps
175
+ run: npm ci
176
+ - name: Install runtime package deps (react for the bundled runtime test)
177
+ # The vite-plugin vitest config globs in the sibling runtime package's
178
+ # `index.test.mjs`, which imports the runtime's `index.js` → `react`.
179
+ # That package keeps `react` in its own deps (lockfile gitignored), so
180
+ # install them here. Without this the bundled run fails to resolve react.
181
+ working-directory: vendor/javascript/ruact-server-functions-runtime
182
+ run: npm install --no-audit --no-fund
183
+ - name: Run vitest (codegen + Ruby↔JS parity + runtime)
184
+ run: npm test
185
+ - name: Type-check emitted accessors (Story 13.4 / FR99)
186
+ run: npm run typecheck
187
+
154
188
  benchmark:
155
189
  # Required status check — fails if memory allocations exceed 120% of baseline.json.
156
190
  name: Memory Benchmark
@@ -177,9 +211,21 @@ jobs:
177
211
  # `[epic-done]` marker in the merge-commit message; major manual for 1.0.0.
178
212
  # Auth is RubyGems Trusted Publishing (OIDC) — satisfies
179
213
  # rubygems_mfa_required. The bump commit carries [skip ci] (no re-trigger).
214
+ #
215
+ # KILL SWITCH (added 2026-06-14): publishing is OFF by default. The job only
216
+ # runs when the repo variable RUACT_AUTO_RELEASE is exactly "true". When the
217
+ # variable is unset (current state), `vars.RUACT_AUTO_RELEASE` is the empty
218
+ # string, the `== 'true'` test is false, and this job is skipped — every
219
+ # other check still runs, merges stay green, nothing is published.
220
+ # Turn ON : gh variable set RUACT_AUTO_RELEASE -b true -R luizcg/ruact
221
+ # Turn OFF: gh variable delete RUACT_AUTO_RELEASE -R luizcg/ruact
222
+ # (or GitHub UI: Settings -> Secrets and variables -> Actions -> Variables)
180
223
  name: Release to RubyGems
181
- needs: [name-propagation, rspec, rubocop, yard, benchmark]
182
- if: github.event_name == 'push' && github.ref == 'refs/heads/main'
224
+ needs: [name-propagation, rspec, rubocop, yard, js, benchmark]
225
+ if: >-
226
+ github.event_name == 'push'
227
+ && github.ref == 'refs/heads/main'
228
+ && vars.RUACT_AUTO_RELEASE == 'true'
183
229
  runs-on: ubuntu-latest
184
230
  permissions:
185
231
  id-token: write
@@ -217,6 +263,12 @@ jobs:
217
263
  print v
218
264
  ' "$KIND")
219
265
  echo "version=$VERSION" >> "$GITHUB_OUTPUT"
266
+ # Resync Gemfile.lock to the bumped path-gem version. Without this the
267
+ # release commit carries a new version.rb but a stale lock, and every
268
+ # frozen-mode job (rubocop/yard/benchmark) goes red on the next push
269
+ # with bundler exit 16 ("gemspecs for path gems changed"). `git commit
270
+ # -am` below then picks up the updated lock alongside version.rb.
271
+ bundle lock --local
220
272
  echo "::notice::Release bump $KIND -> v$VERSION"
221
273
  - uses: rubygems/configure-rubygems-credentials@v2.0.0 # OIDC -> short-lived credential
222
274
  - name: Commit, tag & publish
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 100`
3
- # on 2026-06-06 01:48:31 UTC using RuboCop version 1.85.1.
3
+ # on 2026-06-15 05:49:26 UTC using RuboCop version 1.85.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -14,74 +14,15 @@ Layout/EmptyLinesAroundAttributeAccessor:
14
14
  Exclude:
15
15
  - 'spec/ruact/server_functions/error_payload_spec.rb'
16
16
 
17
- # Offense count: 14
17
+ # Offense count: 10
18
18
  # This cop supports safe autocorrection (--autocorrect).
19
19
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
20
20
  # URISchemes: http, https
21
21
  Layout/LineLength:
22
22
  Exclude:
23
23
  - 'bench/server_functions_dispatch_bench.rb'
24
- - 'lib/ruact/errors.rb'
25
24
  - 'lib/ruact/server_functions/error_suggestion.rb'
26
- - 'spec/ruact/server_functions/endpoint_controller_rescue_spec.rb'
27
25
  - 'spec/ruact/server_functions/error_suggestion_spec.rb'
28
- - 'spec/ruact/server_functions/railtie_integration_spec.rb'
29
- - 'spec/ruact/server_functions/snapshot_spec.rb'
30
-
31
- # Offense count: 1
32
- # Configuration parameters: AllowedMethods.
33
- # AllowedMethods: enums
34
- Lint/ConstantDefinitionInBlock:
35
- Exclude:
36
- - 'spec/ruact/server_functions/csrf_request_spec.rb'
37
-
38
- # Offense count: 1
39
- # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
40
- Metrics/AbcSize:
41
- Exclude:
42
- - 'lib/ruact/controller.rb'
43
-
44
- # Offense count: 1
45
- # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
46
- # AllowedMethods: refine
47
- Metrics/BlockLength:
48
- Exclude:
49
- - 'lib/ruact/controller.rb'
50
-
51
- # Offense count: 1
52
- # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
53
- Metrics/CyclomaticComplexity:
54
- Exclude:
55
- - 'lib/ruact/controller.rb'
56
-
57
- # Offense count: 2
58
- # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
59
- Metrics/MethodLength:
60
- Exclude:
61
- - 'lib/ruact/controller.rb'
62
- - 'lib/ruact/server_action.rb'
63
-
64
- # Offense count: 2
65
- # Configuration parameters: CountComments, Max, CountAsOne.
66
- Metrics/ModuleLength:
67
- Exclude:
68
- - 'spec/**/*'
69
- - 'lib/ruact/controller.rb'
70
- - 'lib/ruact/server_functions/codegen.rb'
71
-
72
- # Offense count: 1
73
- # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
74
- Metrics/PerceivedComplexity:
75
- Exclude:
76
- - 'lib/ruact/controller.rb'
77
-
78
- # Offense count: 1
79
- RSpec/BeforeAfterAll:
80
- Exclude:
81
- - '**/spec/spec_helper.rb'
82
- - '**/spec/rails_helper.rb'
83
- - '**/spec/support/**/*.rb'
84
- - 'spec/ruact/server_functions/dispatch_request_spec.rb'
85
26
 
86
27
  # Offense count: 1
87
28
  # Configuration parameters: Prefixes, AllowedPatterns.
@@ -90,46 +31,6 @@ RSpec/ContextWording:
90
31
  Exclude:
91
32
  - 'spec/ruact/controller_spec.rb'
92
33
 
93
- # Offense count: 2
94
- RSpec/LeakyConstantDeclaration:
95
- Exclude:
96
- - 'spec/ruact/server_functions/csrf_request_spec.rb'
97
-
98
- # Offense count: 1
99
- # Configuration parameters: EnforcedStyle.
100
- # SupportedStyles: have_received, receive
101
- RSpec/MessageSpies:
102
- Exclude:
103
- - 'spec/ruact/server_functions/railtie_integration_spec.rb'
104
-
105
- # Offense count: 5
106
- # Configuration parameters: Max.
107
- RSpec/MultipleExpectations:
108
- Exclude:
109
- - 'spec/ruact/controller_spec.rb'
110
- - 'spec/ruact/server_functions/csrf_request_spec.rb'
111
- - 'spec/ruact/server_functions/endpoint_controller_rescue_spec.rb'
112
- - 'spec/ruact/server_functions/standalone_action_spec.rb'
113
-
114
- # Offense count: 2
115
- RSpec/RemoveConst:
116
- Exclude:
117
- - 'spec/ruact/server_functions/railtie_integration_spec.rb'
118
-
119
- # Offense count: 1
120
- # Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
121
- # SupportedInflectors: default, active_support
122
- RSpec/SpecFilePathFormat:
123
- Exclude:
124
- - '**/spec/routing/**/*'
125
- - 'spec/ruact/server_functions/standalone_action_spec.rb'
126
-
127
- # Offense count: 3
128
- Ruact/NoSharedState:
129
- Exclude:
130
- - 'lib/ruact/controller.rb'
131
- - 'lib/ruact/server_functions/endpoint_controller.rb'
132
-
133
34
  # Offense count: 2
134
35
  # This cop supports unsafe autocorrection (--autocorrect-all).
135
36
  # Configuration parameters: AllowedMethods, AllowedPatterns.
@@ -149,27 +50,14 @@ Style/MixinUsage:
149
50
  Exclude:
150
51
  - 'bench/server_functions_dispatch_bench.rb'
151
52
 
152
- # Offense count: 7
153
- Style/MultilineBlockChain:
154
- Exclude:
155
- - 'spec/ruact/server_functions/registry_spec.rb'
156
- - 'spec/ruact/server_functions/standalone_action_spec.rb'
157
-
158
- # Offense count: 5
53
+ # Offense count: 4
159
54
  # Configuration parameters: AllowedClasses.
160
55
  Style/OneClassPerFile:
161
56
  Exclude:
162
57
  - 'bench/server_functions_dispatch_bench.rb'
163
- - 'spec/ruact/server_functions/csrf_request_spec.rb'
164
58
 
165
59
  # Offense count: 2
166
60
  # This cop supports safe autocorrection (--autocorrect).
167
61
  Style/RedundantFreeze:
168
62
  Exclude:
169
63
  - 'spec/ruact/server_functions/error_payload_spec.rb'
170
-
171
- # Offense count: 1
172
- # Configuration parameters: Max.
173
- Style/SafeNavigationChainLength:
174
- Exclude:
175
- - 'lib/ruact/server_functions/standalone_dispatcher.rb'