ruact 0.0.11 → 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.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +147 -48
  3. data/CONTRIBUTING.md +233 -0
  4. data/README.md +18 -8
  5. data/RELEASING.md +125 -139
  6. data/lib/generators/ruact/install/install_generator.rb +305 -126
  7. data/lib/generators/ruact/install/templates/AGENTS.md.tt +14 -13
  8. data/lib/generators/ruact/install/templates/initializer.rb.tt +29 -7
  9. data/lib/generators/ruact/install/templates/tsconfig.json.tt +3 -0
  10. data/lib/generators/ruact/layout/layout_generator.rb +52 -0
  11. data/lib/generators/ruact/scaffold/templates/controller.rb.tt +5 -3
  12. data/lib/ruact/configuration.rb +65 -13
  13. data/lib/ruact/controller/document_rendering.rb +72 -16
  14. data/lib/ruact/controller/page_rendering.rb +134 -0
  15. data/lib/ruact/controller/pages.rb +116 -0
  16. data/lib/ruact/controller.rb +78 -11
  17. data/lib/ruact/doctor.rb +233 -25
  18. data/lib/ruact/layout_source.rb +29 -7
  19. data/lib/ruact/navigation_boundary.rb +240 -0
  20. data/lib/ruact/packaging.rb +68 -0
  21. data/lib/ruact/railtie.rb +30 -0
  22. data/lib/ruact/server.rb +10 -1
  23. data/lib/ruact/version.rb +1 -1
  24. data/lib/ruact/view_helper.rb +158 -1
  25. data/lib/ruact/views/layouts/ruact.html.erb +32 -0
  26. data/lib/ruact.rb +29 -0
  27. data/vendor/javascript/vite-plugin-ruact/flight-client.test.mjs +321 -0
  28. data/vendor/javascript/vite-plugin-ruact/package-lock.json +11 -0
  29. data/vendor/javascript/vite-plugin-ruact/package.json +1 -0
  30. data/vendor/javascript/vite-plugin-ruact/ruact-router.test.mjs +433 -0
  31. data/vendor/javascript/vite-plugin-ruact/runtime/flight-client.js +14 -3
  32. data/vendor/javascript/vite-plugin-ruact/runtime/ruact-router.js +170 -7
  33. metadata +12 -107
  34. data/.codecov.yml +0 -31
  35. data/.github/workflows/ci.yml +0 -284
  36. data/.github/workflows/server-functions-bench.yml +0 -54
  37. data/.rubocop.yml +0 -107
  38. data/.rubocop_todo.yml +0 -63
  39. data/Rakefile +0 -10
  40. data/bench/server_functions_dispatch_bench.rb +0 -276
  41. data/bench/server_functions_dispatch_bench.results.md +0 -150
  42. data/docs/internal/README.md +0 -9
  43. data/docs/internal/decisions/server-functions-api.md +0 -2236
  44. data/spec/benchmarks/baseline.json +0 -12
  45. data/spec/benchmarks/render_pipeline_benchmark_spec.rb +0 -109
  46. data/spec/fixtures/flight/README.md +0 -136
  47. data/spec/fixtures/flight/array.txt +0 -1
  48. data/spec/fixtures/flight/as_json_object.txt +0 -2
  49. data/spec/fixtures/flight/bigint.txt +0 -1
  50. data/spec/fixtures/flight/boolean_false.txt +0 -1
  51. data/spec/fixtures/flight/boolean_true.txt +0 -1
  52. data/spec/fixtures/flight/client_component_with_props.txt +0 -2
  53. data/spec/fixtures/flight/client_reference.txt +0 -2
  54. data/spec/fixtures/flight/hash.txt +0 -1
  55. data/spec/fixtures/flight/infinity.txt +0 -1
  56. data/spec/fixtures/flight/nan.txt +0 -1
  57. data/spec/fixtures/flight/negative_infinity.txt +0 -1
  58. data/spec/fixtures/flight/nil.txt +0 -1
  59. data/spec/fixtures/flight/number_float.txt +0 -1
  60. data/spec/fixtures/flight/number_integer.txt +0 -1
  61. data/spec/fixtures/flight/react_element_no_props.txt +0 -1
  62. data/spec/fixtures/flight/redirect_row.txt +0 -1
  63. data/spec/fixtures/flight/serializable_object.txt +0 -2
  64. data/spec/fixtures/flight/string_basic.txt +0 -1
  65. data/spec/fixtures/flight/string_dollar_escape.txt +0 -1
  66. data/spec/fixtures/flight/undefined.txt +0 -1
  67. data/spec/fixtures/readme/children-error.html.erb +0 -3
  68. data/spec/fixtures/readme/children-error.txt +0 -1
  69. data/spec/fixtures/story_7_9_views/controller_request_spec_support/demo/show.html.erb +0 -3
  70. data/spec/fixtures/story_7_9_views/controller_request_spec_support/errors_demo/new.html.erb +0 -3
  71. data/spec/fixtures/story_7_9_views/controller_request_spec_support/exploding_layout_demo/show.html.erb +0 -3
  72. data/spec/fixtures/story_7_9_views/controller_request_spec_support/ghost_layout_demo/show.html.erb +0 -3
  73. data/spec/fixtures/story_7_9_views/controller_request_spec_support/layout_demo/show.html.erb +0 -3
  74. data/spec/fixtures/story_7_9_views/controller_request_spec_support/rootless_layout_demo/show.html.erb +0 -3
  75. data/spec/fixtures/story_7_9_views/controller_request_spec_support/unwired_layout_demo/show.html.erb +0 -3
  76. data/spec/fixtures/story_7_9_views/layouts/bare_host.html.erb +0 -16
  77. data/spec/fixtures/story_7_9_views/layouts/exploding_host.html.erb +0 -24
  78. data/spec/fixtures/story_7_9_views/layouts/rootless_host.html.erb +0 -15
  79. data/spec/fixtures/story_7_9_views/layouts/ruact_host.html.erb +0 -17
  80. data/spec/readme_demo_message_spec.rb +0 -67
  81. data/spec/readme_spec.rb +0 -282
  82. data/spec/ruact/client_manifest_spec.rb +0 -270
  83. data/spec/ruact/component_contract_spec.rb +0 -119
  84. data/spec/ruact/configuration_spec.rb +0 -518
  85. data/spec/ruact/controller_request_spec.rb +0 -671
  86. data/spec/ruact/controller_spec.rb +0 -343
  87. data/spec/ruact/doctor_spec.rb +0 -769
  88. data/spec/ruact/erb_preprocessor_hook_spec.rb +0 -55
  89. data/spec/ruact/erb_preprocessor_spec.rb +0 -361
  90. data/spec/ruact/errors_spec.rb +0 -93
  91. data/spec/ruact/flight/renderer_spec.rb +0 -133
  92. data/spec/ruact/flight/serializer_spec.rb +0 -494
  93. data/spec/ruact/html_converter_spec.rb +0 -375
  94. data/spec/ruact/install_generator_spec.rb +0 -1549
  95. data/spec/ruact/layout_source_spec.rb +0 -108
  96. data/spec/ruact/manifest_resolver_spec.rb +0 -174
  97. data/spec/ruact/query_request_spec.rb +0 -706
  98. data/spec/ruact/query_spec.rb +0 -105
  99. data/spec/ruact/railtie_spec.rb +0 -155
  100. data/spec/ruact/render_context_spec.rb +0 -58
  101. data/spec/ruact/render_pipeline_concurrency_spec.rb +0 -78
  102. data/spec/ruact/render_pipeline_spec.rb +0 -928
  103. data/spec/ruact/scaffold_generator_spec.rb +0 -1849
  104. data/spec/ruact/serializable_spec.rb +0 -179
  105. data/spec/ruact/server_bucket_request_spec.rb +0 -785
  106. data/spec/ruact/server_function_name_spec.rb +0 -53
  107. data/spec/ruact/server_functions/backtrace_cleaner_spec.rb +0 -63
  108. data/spec/ruact/server_functions/bucket_two_payload_spec.rb +0 -200
  109. data/spec/ruact/server_functions/codegen_spec.rb +0 -397
  110. data/spec/ruact/server_functions/error_payload_spec.rb +0 -222
  111. data/spec/ruact/server_functions/error_suggestion_spec.rb +0 -79
  112. data/spec/ruact/server_functions/introspection_spec.rb +0 -135
  113. data/spec/ruact/server_functions/name_bridge_spec.rb +0 -212
  114. data/spec/ruact/server_functions/query_context_spec.rb +0 -72
  115. data/spec/ruact/server_functions/query_source_spec.rb +0 -193
  116. data/spec/ruact/server_functions/railtie_integration_spec.rb +0 -215
  117. data/spec/ruact/server_functions/rake_spec.rb +0 -86
  118. data/spec/ruact/server_functions/route_source_spec.rb +0 -202
  119. data/spec/ruact/server_functions/snapshot_spec.rb +0 -96
  120. data/spec/ruact/server_functions/snapshot_writer_spec.rb +0 -71
  121. data/spec/ruact/server_rescue_request_spec.rb +0 -416
  122. data/spec/ruact/server_spec.rb +0 -179
  123. data/spec/ruact/server_upload_request_spec.rb +0 -311
  124. data/spec/ruact/signed_references_spec.rb +0 -164
  125. data/spec/ruact/string_distance_spec.rb +0 -38
  126. data/spec/ruact/tasks_json_introspection_spec.rb +0 -141
  127. data/spec/ruact/testing/have_ruact_component_spec.rb +0 -170
  128. data/spec/ruact/testing/no_production_load_spec.rb +0 -41
  129. data/spec/ruact/validation_errors_spec.rb +0 -116
  130. data/spec/ruact/view_helper_spec.rb +0 -131
  131. data/spec/spec_helper.rb +0 -77
  132. data/spec/support/fixtures/pixel.png +0 -0
  133. data/spec/support/flight_wire_parser.rb +0 -21
  134. data/spec/support/flight_wire_parser_spec.rb +0 -93
  135. data/spec/support/matchers/flight_fixture_matcher.rb +0 -130
  136. data/spec/support/matchers/flight_fixture_matcher_spec.rb +0 -250
  137. data/spec/support/rails_stub.rb +0 -115
@@ -275,6 +275,101 @@ function _buildFormData(form, submitter) {
275
275
  }
276
276
  }
277
277
 
278
+ // ---------------------------------------------------------------------------
279
+ // Story 17.0f — the navigation boundary
280
+ // ---------------------------------------------------------------------------
281
+
282
+ function _isNativeBoundary(response) {
283
+ return response.headers?.get("ruact-boundary") === "native";
284
+ }
285
+
286
+ function _isFlight(response) {
287
+ return (response.headers?.get("content-type") || "").includes("text/x-component");
288
+ }
289
+
290
+ // A full document load of the final URL (after any redirect the fetch
291
+ // followed). `replace` for back/forward, so no entry is pushed mid-history.
292
+ //
293
+ // `response.url` never carries the #fragment (Fetch strips it), so the one
294
+ // the link asked for is put back.
295
+ function _fullLoad(response, targetUrl, { replace = false } = {}) {
296
+ const requested = new URL(targetUrl, location.href);
297
+ const destination = new URL(response.url || requested.href);
298
+ if (!destination.hash && requested.hash) destination.hash = requested.hash;
299
+ if (replace) location.replace(destination.href);
300
+ else location.assign(destination.href);
301
+ }
302
+
303
+ function _escapedFormMessage(method, targetUrl, response) {
304
+ const path = new URL(targetUrl, location.href).pathname;
305
+ const type = response.headers?.get("content-type") || "no content type";
306
+ return `[ruact] ${method} ${path} answered ${response.status} with ${type}, not a ruact page. ` +
307
+ "The action already ran, so ruact will not submit the form again. " +
308
+ 'Add data-ruact="false" to this <form> to let the browser submit it, ' +
309
+ "or have the action answer through ruact.";
310
+ }
311
+
312
+ // Submits the form as the browser would, WITHOUT dispatching a `submit` event —
313
+ // so neither this router nor Turbo intercepts it again. The browser only sends
314
+ // the clicked button's `name=value` (and honours its `formaction` / `formmethod`
315
+ // / `formtarget`) when that button is the submitter, which `submit()` has no way
316
+ // to express: both are carried over onto the form first.
317
+ //
318
+ // Everything added to the form is taken back right after: `submit()` builds its
319
+ // entry list synchronously, and a page that survives the submit (a download, a
320
+ // 204, a return from the back-forward cache) must not keep the last button's
321
+ // overrides and value for the next one.
322
+ //
323
+ // A form rendered by a React component has no `authenticity_token` field — the
324
+ // router's own fetch sent the token as a header. A native submit cannot, so the
325
+ // token from `<meta name="csrf-token">` goes in as a field, the way rails-ujs
326
+ // does it.
327
+ const _SUBMITTER_OVERRIDES = [
328
+ ["formaction", "action"], ["formmethod", "method"], ["formtarget", "target"], ["formenctype", "enctype"],
329
+ ];
330
+
331
+ function _nativeSubmit(form, submitter) {
332
+ const restore = [];
333
+ const added = [];
334
+
335
+ if (submitter) {
336
+ for (const [override, attribute] of _SUBMITTER_OVERRIDES) {
337
+ if (!submitter.hasAttribute(override)) continue;
338
+ restore.push([attribute, form.hasAttribute(attribute) ? form.getAttribute(attribute) : null]);
339
+ form.setAttribute(attribute, submitter.getAttribute(override));
340
+ }
341
+ if (submitter.name) added.push(_hiddenField(submitter.name, submitter.value));
342
+ }
343
+
344
+ const csrfParam = document.querySelector('meta[name="csrf-param"]')?.content;
345
+ const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content;
346
+ if (csrfParam && csrfToken && !_hasField(form, csrfParam)) added.push(_hiddenField(csrfParam, csrfToken));
347
+
348
+ added.forEach((field) => form.appendChild(field));
349
+ try {
350
+ HTMLFormElement.prototype.submit.call(form);
351
+ } finally {
352
+ added.forEach((field) => field.remove?.());
353
+ restore.forEach(([attribute, value]) => {
354
+ if (value === null) form.removeAttribute?.(attribute);
355
+ else form.setAttribute(attribute, value);
356
+ });
357
+ }
358
+ }
359
+
360
+ function _hiddenField(name, value) {
361
+ const field = document.createElement("input");
362
+ field.type = "hidden";
363
+ field.name = name;
364
+ field.value = value;
365
+ return field;
366
+ }
367
+
368
+ function _hasField(form, name) {
369
+ const quoted = name.replace(/["\\]/g, "\\$&");
370
+ return Boolean(form.elements?.namedItem?.(name) ?? form.querySelector?.(`[name="${quoted}"]`));
371
+ }
372
+
278
373
  async function _submitForm(form, submitter = null) {
279
374
  clearPendingChunks();
280
375
 
@@ -317,7 +412,18 @@ async function _submitForm(form, submitter = null) {
317
412
  headers,
318
413
  signal: controller.signal,
319
414
  });
320
- await _processFlightResponse(response, { push: true, targetUrl: action });
415
+ // Story 17.0f — not a ruact page, and the action did NOT run: this native
416
+ // submit is its one and only run, and its real response (a 422 with the
417
+ // validation errors included) is what the user sees.
418
+ if (_isNativeBoundary(response)) {
419
+ // The boundary answer came at the END of a redirect the fetch followed:
420
+ // the form's action already ran (a real 3xx, e.g. to another scheme), and
421
+ // resubmitting would run it twice. Load where it redirected to instead.
422
+ if (response.redirected) _fullLoad(response, action);
423
+ else _nativeSubmit(form, submitter);
424
+ return;
425
+ }
426
+ await _processFlightResponse(response, { push: true, targetUrl: action, method: htmlMethod });
321
427
  } catch (err) {
322
428
  if (err.name === "AbortError") return;
323
429
  console.error("[ruact-router] Form submission error:", err);
@@ -330,7 +436,9 @@ async function _submitForm(form, submitter = null) {
330
436
  // ---------------------------------------------------------------------------
331
437
 
332
438
  function handlePopstate() {
333
- navigate(location.pathname + location.search + location.hash, { push: false, scroll: false });
439
+ // Story 17.0f — `replace`: if this entry turns out not to be a ruact page, the
440
+ // full load must not push a NEW entry into the history being walked.
441
+ navigate(location.pathname + location.search + location.hash, { push: false, scroll: false, replace: true });
334
442
  }
335
443
 
336
444
  // ---------------------------------------------------------------------------
@@ -346,7 +454,7 @@ function handlePopstate() {
346
454
  * REJECTS on a failed Flight fetch — without this, callers cannot
347
455
  * branch on success vs. failure of a programmatic refetch.
348
456
  */
349
- async function navigate(url, { push = true, scroll = true, throwOnError = false } = {}) {
457
+ async function navigate(url, { push = true, scroll = true, throwOnError = false, replace = false } = {}) {
350
458
  // Clear stale lazy refs from any previous streaming navigation
351
459
  clearPendingChunks();
352
460
 
@@ -359,11 +467,21 @@ async function navigate(url, { push = true, scroll = true, throwOnError = false
359
467
  headers: { Accept: "text/x-component", "Ruact-Request": "1" },
360
468
  signal: controller.signal,
361
469
  });
470
+ // Story 17.0f — the server said the destination is not a ruact page, and
471
+ // ran nothing to say so. The browser takes it from here.
472
+ if (_isNativeBoundary(response)) {
473
+ // A caller that asked to be told (revalidate) refetches the page it is
474
+ // ON; "not a ruact page" there is a failure to report, not a reload.
475
+ if (throwOnError) throw new Error(`[ruact] ${url} is not a ruact page`);
476
+ _fullLoad(response, url, { replace });
477
+ return;
478
+ }
362
479
  await _processFlightResponse(response, {
363
480
  push,
364
481
  targetUrl: url,
365
482
  scroll,
366
483
  throwOnError,
484
+ replace,
367
485
  });
368
486
  } catch (err) {
369
487
  if (err.name === "AbortError") {
@@ -380,8 +498,47 @@ async function navigate(url, { push = true, scroll = true, throwOnError = false
380
498
  // Shared Flight response processor (used by navigate + _submitForm)
381
499
  // ---------------------------------------------------------------------------
382
500
 
383
- async function _processFlightResponse(response, { push, targetUrl, scroll = true, throwOnError = false }) {
384
- if (!response.ok) {
501
+ async function _processFlightResponse(response, {
502
+ push, targetUrl, scroll = true, throwOnError = false, replace = false, method = "GET",
503
+ }) {
504
+ // Story 17.0f — a response that is not Flight escaped the server's boundary
505
+ // classifier. Feeding it to the line parser was the old dead click: every HTML
506
+ // line parses to null, nothing renders, nothing reports.
507
+ //
508
+ // A non-Flight GET — a page, or an error page (404, 500, a 401 from auth) —
509
+ // is loaded in full so the user SEES it: the default app passes no onError,
510
+ // and a console line is a dead click by another name. Repeating a GET is
511
+ // harmless. A caller that asked to be told (`throwOnError`: revalidate)
512
+ // gets the error instead of a reload.
513
+ if (!_isFlight(response)) {
514
+ if (method === "GET" && !throwOnError) {
515
+ _fullLoad(response, targetUrl, { replace });
516
+ return;
517
+ }
518
+ // A form whose action answered HTML — it ran, so it will not be resubmitted.
519
+ // Only a 2xx or a 422 is that; a 403 (CSRF) or a 500 is a failure, below.
520
+ if (method !== "GET" && (response.ok || response.status === 422)) {
521
+ const err = new Error(_escapedFormMessage(method, targetUrl, response));
522
+ console.error(err.message);
523
+ _onError?.(err);
524
+ if (throwOnError) throw err;
525
+ return;
526
+ }
527
+ if (response.ok) {
528
+ const err = new Error(`[ruact] ${targetUrl} did not answer with a ruact response`);
529
+ console.error(err.message);
530
+ _onError?.(err);
531
+ if (throwOnError) throw err;
532
+ return;
533
+ }
534
+ }
535
+
536
+ // Story 17.0i — a Flight 422 is a page: `render :new, status:
537
+ // :unprocessable_entity` re-rendering a form with its validation errors. The
538
+ // errors are the content, not a transport failure. Every other non-2xx stays
539
+ // a failure — an HTML 422 (Rails' own error page) included.
540
+ const unprocessable = response.status === 422 && _isFlight(response);
541
+ if (!response.ok && !unprocessable) {
385
542
  const msg = `[ruact] Request failed: ${response.status} ${response.statusText}`;
386
543
  console.error(msg);
387
544
  const err = new Error(msg);
@@ -392,6 +549,12 @@ async function _processFlightResponse(response, { push, targetUrl, scroll = true
392
549
  return;
393
550
  }
394
551
 
552
+ // Story 17.0i — a form's 422 re-render keeps the form's URL: the POST URL is
553
+ // not one a reload or Back can ask for again (a reload of `/posts` would be
554
+ // the index). Unless the fetch followed a redirect: it then ended on a GET,
555
+ // and that URL is the page being shown.
556
+ const pushEntry = push && !(unprocessable && method !== "GET" && !response.redirected);
557
+
395
558
  // Use final URL after any redirects (response.url is the resolved URL).
396
559
  const finalPath = response.url
397
560
  ? (() => { const u = new URL(response.url); return u.pathname + u.search + u.hash; })()
@@ -422,7 +585,7 @@ async function _processFlightResponse(response, { push, targetUrl, scroll = true
422
585
  }
423
586
  // Normal case: build tree and render immediately.
424
587
  const tree = buildTreeFromRows(rows, _moduleRegistry);
425
- if (push) history.pushState(null, "", finalPath);
588
+ if (pushEntry) history.pushState(null, "", finalPath);
426
589
  _onNavigate(tree);
427
590
  if (scroll) window.scrollTo(0, 0);
428
591
  initialTreeSet = true;
@@ -466,7 +629,7 @@ async function _processFlightResponse(response, { push, targetUrl, scroll = true
466
629
  // Fallback: if row 0 never triggered (shouldn't happen with valid server)
467
630
  if (!initialTreeSet && !redirected && rows.has(0)) {
468
631
  const tree = buildTreeFromRows(rows, _moduleRegistry);
469
- if (push) history.pushState(null, "", finalPath);
632
+ if (pushEntry) history.pushState(null, "", finalPath);
470
633
  _onNavigate(tree);
471
634
  if (scroll) window.scrollTo(0, 0);
472
635
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruact
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luiz Garcia
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-25 00:00:00.000000000 Z
11
+ date: 2026-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -36,21 +36,12 @@ executables: []
36
36
  extensions: []
37
37
  extra_rdoc_files: []
38
38
  files:
39
- - ".codecov.yml"
40
- - ".github/workflows/ci.yml"
41
- - ".github/workflows/server-functions-bench.yml"
42
- - ".rubocop.yml"
43
- - ".rubocop_todo.yml"
44
39
  - CHANGELOG.md
40
+ - CONTRIBUTING.md
45
41
  - LICENSE.txt
46
42
  - README.md
47
43
  - RELEASING.md
48
- - Rakefile
49
44
  - SECURITY.md
50
- - bench/server_functions_dispatch_bench.rb
51
- - bench/server_functions_dispatch_bench.results.md
52
- - docs/internal/README.md
53
- - docs/internal/decisions/server-functions-api.md
54
45
  - lib/generators/ruact/install/install_generator.rb
55
46
  - lib/generators/ruact/install/templates/AGENTS.md.tt
56
47
  - lib/generators/ruact/install/templates/Procfile.dev.tt
@@ -60,6 +51,7 @@ files:
60
51
  - lib/generators/ruact/install/templates/package.json.tt
61
52
  - lib/generators/ruact/install/templates/tsconfig.json.tt
62
53
  - lib/generators/ruact/install/templates/vite.config.js.tt
54
+ - lib/generators/ruact/layout/layout_generator.rb
63
55
  - lib/generators/ruact/scaffold/scaffold_attribute.rb
64
56
  - lib/generators/ruact/scaffold/scaffold_form_helpers.rb
65
57
  - lib/generators/ruact/scaffold/scaffold_generator.rb
@@ -84,6 +76,8 @@ files:
84
76
  - lib/ruact/configuration.rb
85
77
  - lib/ruact/controller.rb
86
78
  - lib/ruact/controller/document_rendering.rb
79
+ - lib/ruact/controller/page_rendering.rb
80
+ - lib/ruact/controller/pages.rb
87
81
  - lib/ruact/doctor.rb
88
82
  - lib/ruact/erb_preprocessor.rb
89
83
  - lib/ruact/erb_preprocessor_hook.rb
@@ -97,6 +91,8 @@ files:
97
91
  - lib/ruact/html_converter.rb
98
92
  - lib/ruact/layout_source.rb
99
93
  - lib/ruact/manifest_resolver.rb
94
+ - lib/ruact/navigation_boundary.rb
95
+ - lib/ruact/packaging.rb
100
96
  - lib/ruact/query.rb
101
97
  - lib/ruact/railtie.rb
102
98
  - lib/ruact/render_context.rb
@@ -132,6 +128,7 @@ files:
132
128
  - lib/ruact/validation_errors_collector.rb
133
129
  - lib/ruact/version.rb
134
130
  - lib/ruact/view_helper.rb
131
+ - lib/ruact/views/layouts/ruact.html.erb
135
132
  - lib/rubocop/cop/ruact.rb
136
133
  - lib/rubocop/cop/ruact/no_extend_self.rb
137
134
  - lib/rubocop/cop/ruact/no_io_in_flight.rb
@@ -139,112 +136,20 @@ files:
139
136
  - lib/tasks/benchmark.rake
140
137
  - lib/tasks/ruact.rake
141
138
  - sig/ruact.rbs
142
- - spec/benchmarks/baseline.json
143
- - spec/benchmarks/render_pipeline_benchmark_spec.rb
144
- - spec/fixtures/flight/README.md
145
- - spec/fixtures/flight/array.txt
146
- - spec/fixtures/flight/as_json_object.txt
147
- - spec/fixtures/flight/bigint.txt
148
- - spec/fixtures/flight/boolean_false.txt
149
- - spec/fixtures/flight/boolean_true.txt
150
- - spec/fixtures/flight/client_component_with_props.txt
151
- - spec/fixtures/flight/client_reference.txt
152
- - spec/fixtures/flight/hash.txt
153
- - spec/fixtures/flight/infinity.txt
154
- - spec/fixtures/flight/nan.txt
155
- - spec/fixtures/flight/negative_infinity.txt
156
- - spec/fixtures/flight/nil.txt
157
- - spec/fixtures/flight/number_float.txt
158
- - spec/fixtures/flight/number_integer.txt
159
- - spec/fixtures/flight/react_element_no_props.txt
160
- - spec/fixtures/flight/redirect_row.txt
161
- - spec/fixtures/flight/serializable_object.txt
162
- - spec/fixtures/flight/string_basic.txt
163
- - spec/fixtures/flight/string_dollar_escape.txt
164
- - spec/fixtures/flight/undefined.txt
165
- - spec/fixtures/readme/children-error.html.erb
166
- - spec/fixtures/readme/children-error.txt
167
- - spec/fixtures/story_7_9_views/controller_request_spec_support/demo/show.html.erb
168
- - spec/fixtures/story_7_9_views/controller_request_spec_support/errors_demo/new.html.erb
169
- - spec/fixtures/story_7_9_views/controller_request_spec_support/exploding_layout_demo/show.html.erb
170
- - spec/fixtures/story_7_9_views/controller_request_spec_support/ghost_layout_demo/show.html.erb
171
- - spec/fixtures/story_7_9_views/controller_request_spec_support/layout_demo/show.html.erb
172
- - spec/fixtures/story_7_9_views/controller_request_spec_support/rootless_layout_demo/show.html.erb
173
- - spec/fixtures/story_7_9_views/controller_request_spec_support/unwired_layout_demo/show.html.erb
174
- - spec/fixtures/story_7_9_views/layouts/bare_host.html.erb
175
- - spec/fixtures/story_7_9_views/layouts/exploding_host.html.erb
176
- - spec/fixtures/story_7_9_views/layouts/rootless_host.html.erb
177
- - spec/fixtures/story_7_9_views/layouts/ruact_host.html.erb
178
- - spec/readme_demo_message_spec.rb
179
- - spec/readme_spec.rb
180
- - spec/ruact/client_manifest_spec.rb
181
- - spec/ruact/component_contract_spec.rb
182
- - spec/ruact/configuration_spec.rb
183
- - spec/ruact/controller_request_spec.rb
184
- - spec/ruact/controller_spec.rb
185
- - spec/ruact/doctor_spec.rb
186
- - spec/ruact/erb_preprocessor_hook_spec.rb
187
- - spec/ruact/erb_preprocessor_spec.rb
188
- - spec/ruact/errors_spec.rb
189
- - spec/ruact/flight/renderer_spec.rb
190
- - spec/ruact/flight/serializer_spec.rb
191
- - spec/ruact/html_converter_spec.rb
192
- - spec/ruact/install_generator_spec.rb
193
- - spec/ruact/layout_source_spec.rb
194
- - spec/ruact/manifest_resolver_spec.rb
195
- - spec/ruact/query_request_spec.rb
196
- - spec/ruact/query_spec.rb
197
- - spec/ruact/railtie_spec.rb
198
- - spec/ruact/render_context_spec.rb
199
- - spec/ruact/render_pipeline_concurrency_spec.rb
200
- - spec/ruact/render_pipeline_spec.rb
201
- - spec/ruact/scaffold_generator_spec.rb
202
- - spec/ruact/serializable_spec.rb
203
- - spec/ruact/server_bucket_request_spec.rb
204
- - spec/ruact/server_function_name_spec.rb
205
- - spec/ruact/server_functions/backtrace_cleaner_spec.rb
206
- - spec/ruact/server_functions/bucket_two_payload_spec.rb
207
- - spec/ruact/server_functions/codegen_spec.rb
208
- - spec/ruact/server_functions/error_payload_spec.rb
209
- - spec/ruact/server_functions/error_suggestion_spec.rb
210
- - spec/ruact/server_functions/introspection_spec.rb
211
- - spec/ruact/server_functions/name_bridge_spec.rb
212
- - spec/ruact/server_functions/query_context_spec.rb
213
- - spec/ruact/server_functions/query_source_spec.rb
214
- - spec/ruact/server_functions/railtie_integration_spec.rb
215
- - spec/ruact/server_functions/rake_spec.rb
216
- - spec/ruact/server_functions/route_source_spec.rb
217
- - spec/ruact/server_functions/snapshot_spec.rb
218
- - spec/ruact/server_functions/snapshot_writer_spec.rb
219
- - spec/ruact/server_rescue_request_spec.rb
220
- - spec/ruact/server_spec.rb
221
- - spec/ruact/server_upload_request_spec.rb
222
- - spec/ruact/signed_references_spec.rb
223
- - spec/ruact/string_distance_spec.rb
224
- - spec/ruact/tasks_json_introspection_spec.rb
225
- - spec/ruact/testing/have_ruact_component_spec.rb
226
- - spec/ruact/testing/no_production_load_spec.rb
227
- - spec/ruact/validation_errors_spec.rb
228
- - spec/ruact/view_helper_spec.rb
229
- - spec/spec_helper.rb
230
- - spec/support/fixtures/pixel.png
231
- - spec/support/flight_wire_parser.rb
232
- - spec/support/flight_wire_parser_spec.rb
233
- - spec/support/matchers/flight_fixture_matcher.rb
234
- - spec/support/matchers/flight_fixture_matcher_spec.rb
235
- - spec/support/rails_stub.rb
236
139
  - vendor/javascript/ruact-server-functions-runtime/index.d.ts
237
140
  - vendor/javascript/ruact-server-functions-runtime/index.js
238
141
  - vendor/javascript/ruact-server-functions-runtime/index.test.mjs
239
142
  - vendor/javascript/ruact-server-functions-runtime/package.json
240
143
  - vendor/javascript/ruact-server-functions-runtime/usequery.test.mjs
241
144
  - vendor/javascript/vite-plugin-ruact/bootstrap.test.mjs
145
+ - vendor/javascript/vite-plugin-ruact/flight-client.test.mjs
242
146
  - vendor/javascript/vite-plugin-ruact/index.js
243
147
  - vendor/javascript/vite-plugin-ruact/manifest-contract.test.mjs
244
148
  - vendor/javascript/vite-plugin-ruact/manifest-http.test.mjs
245
149
  - vendor/javascript/vite-plugin-ruact/package-lock.json
246
150
  - vendor/javascript/vite-plugin-ruact/package.json
247
151
  - vendor/javascript/vite-plugin-ruact/registry.test.mjs
152
+ - vendor/javascript/vite-plugin-ruact/ruact-router.test.mjs
248
153
  - vendor/javascript/vite-plugin-ruact/runtime/bootstrap.jsx
249
154
  - vendor/javascript/vite-plugin-ruact/runtime/flight-client.js
250
155
  - vendor/javascript/vite-plugin-ruact/runtime/ruact-router.js
data/.codecov.yml DELETED
@@ -1,31 +0,0 @@
1
- # Codecov configuration for the ruact gem.
2
- # Story 6.7 — coverage is informativo (not a CI gate); Codecov reports status
3
- # but never fails a PR. Diff coverage targets (90% line / 80% branch) are
4
- # project DoD, surfaced via the per-PR comment for visibility.
5
-
6
- coverage:
7
- status:
8
- project:
9
- default:
10
- informational: true
11
- target: auto
12
- threshold: 1%
13
- patch:
14
- default:
15
- informational: true
16
- target: 90%
17
- threshold: 0%
18
-
19
- comment:
20
- layout: "diff, files"
21
- behavior: default
22
- require_changes: false
23
-
24
- flags:
25
- gem:
26
- # Paths are relative to the gem repo root (where this CI runs and uploads
27
- # from). lcov.info emits source paths like `./lib/ruact.rb`; Codecov
28
- # normalizes the leading `./` so a `lib/` prefix matches.
29
- paths:
30
- - lib/
31
- carryforward: false