react-manifest-rails 0.2.31 → 0.2.33

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: fc0a4a583ea6c0b488c1fc9e4c0af46dec90e4ecdd6b93cd7eae48267ffdbfaa
4
- data.tar.gz: 1a00e3b56139db55d5c473e22bc35cd43e2fc1dcb3ee50700602344c09d0c4db
3
+ metadata.gz: 03532c58c1ba02316a423460c591adf2b8caa7d6366ff89abfc5c344d1e3a8fc
4
+ data.tar.gz: 3ab9a668ad0196bec652c804535307f788a7b6a9abea8418bb3c206d6f6ddba6
5
5
  SHA512:
6
- metadata.gz: b6db17954b9a91e080c0074ce203d322af67ba58d887be9ae4a1ada51add9fe3d36f7fc256b1587c274c2315c9324caa7576421c19740a6aeab40fa85f3f5606
7
- data.tar.gz: 49dc6ae440709098ace838c583f492a516fa5abd0b1b332525cd3803ed3787ed656cd23871b53ad8cb91908a4c0d62e0f9d96b8394180fe950da8ee405068d6c
6
+ metadata.gz: 6ff77f4444719e08a35032a2b07bc2d6e0621d49a5db73e2b77880bbddd0172f8c3f2aea1b38b3ce40ff7feaad8d59a141fa7edabe0ce8430091f89656904a42
7
+ data.tar.gz: d683a77dbcb098e2f5b08c74b1b36dac9d53e56587bf6ec7e958b5f0af25701d98fb9f70a305ceeff2ee0e2656bb81112fddf60cb61f33f21029bf6b445b8291
data/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.33] - 2026-07-01
11
+
12
+ ### Fixed
13
+ - `resolve_bundle_for_component`/`resolve_bundles_for_component(_direct)` (used by the `react_component` view helper) now pick up new controllers and components added while a development server is still running. Their `component_maps` cache is keyed only on config values, not on what's on disk, so once anything primed the cache (any earlier `react_component` call in the process), a controller dir or component added afterward was invisible until the process restarted — `react_component` would silently render with no bundle injected. The file watcher now invalidates this cache on every file change, the same way it already invalidates the scanner's per-file symbol cache.
14
+
15
+ ## [0.2.32] - 2026-07-01
16
+
17
+ ### Added
18
+ - Generation now removes AUTO-GENERATED manifests whose `ux/app/<controller>/` directory no longer exists (renamed or deleted). Previously these were left behind indefinitely, still `//= require`-ing source files that no longer existed — a landmine for `assets:precompile`. Pinned (non-AUTO-GENERATED) files are never touched, and dry-run mode only logs what would be removed.
19
+
20
+ ### Changed
21
+ - `config.stdout_logging` now defaults to `false`. `Rails.logger` always receives ReactManifest's status lines regardless of this flag; `stdout_logging` only controls an *additional* direct print to the terminal. Many development setups already have `Rails.logger` broadcast to stdout (`RAILS_LOG_TO_STDOUT`, Docker, `bin/dev`/Foreman), so the previous default of `true` printed every "File change detected" / "N manifest(s) written" line twice. Set `config.stdout_logging = true` explicitly if your `Rails.logger` does not already surface output in your terminal.
22
+
10
23
  ## [0.2.31] - 2026-07-01
11
24
 
12
25
  ### Fixed
data/README.md CHANGED
@@ -108,6 +108,8 @@ Files carry an `AUTO-GENERATED` header. Any file without it is never overwritten
108
108
 
109
109
  Writes are atomic (temp file + rename) and idempotent (SHA-256 comparison skips unchanged files).
110
110
 
111
+ If a `ux/app/<controller>/` directory is renamed or deleted, its manifest is removed automatically on the next generation (dev file watcher, boot, or `rails react_manifest:generate`) — pinned files are never removed this way.
112
+
111
113
  ## Asset Compilation & Minification
112
114
 
113
115
  The generated files are standard Sprockets manifests — `//= require` directives only. Sprockets processes them identically to `application.js`:
@@ -133,7 +135,7 @@ ReactManifest.configure do |config|
133
135
  config.size_threshold_kb = 500 # warn if a bundle exceeds this
134
136
  config.dry_run = false # never write; only print what would change
135
137
  config.verbose = false # extra diagnostic detail
136
- config.stdout_logging = true # print status lines to terminal
138
+ config.stdout_logging = false # also print status lines directly to stdout (see note below)
137
139
  end
138
140
  ```
139
141
 
@@ -144,6 +146,7 @@ end
144
146
  - **`dry_run`**: also honoured by `DRY_RUN=1` environment variable at runtime.
145
147
  - **`extensions`**: add `ts` and `tsx` to enable TypeScript source detection.
146
148
  - **`external_roots` / `external_providers`**: do not point these at files already inside shared `ux/` dirs (`components/`, `hooks/`, `lib/`, etc.). The generator now skips those overlaps to prevent duplicate declarations in browser runtime.
149
+ - **`stdout_logging`**: `Rails.logger` always receives status lines regardless of this flag. Turn this on only if your `Rails.logger` does *not* already print to your terminal in development — if it does (common with `RAILS_LOG_TO_STDOUT`, Docker, or `bin/dev`/Foreman setups), enabling this prints every line twice.
147
150
 
148
151
  ## Commands
149
152
 
@@ -50,8 +50,13 @@ module ReactManifest
50
50
  # Extra diagnostic logging (summary lines and richer error context).
51
51
  attr_accessor :verbose
52
52
 
53
- # Emit ReactManifest status lines to stdout in development.
54
- # Independent from Rails.logger output.
53
+ # Also print ReactManifest status lines directly to stdout, in addition
54
+ # to Rails.logger (which always receives them regardless of this flag).
55
+ # Off by default: many development setups already have Rails.logger
56
+ # broadcast to the terminal (RAILS_LOG_TO_STDOUT, Docker/Foreman, etc.),
57
+ # and enabling this on top of that prints every line twice. Turn it on
58
+ # only if your Rails.logger does NOT already surface output in your
59
+ # terminal and you want a guaranteed visible line per event.
55
60
  attr_accessor :stdout_logging
56
61
 
57
62
  # Explicit symbol-to-require-path mapping for external globals.
@@ -88,7 +93,7 @@ module ReactManifest
88
93
  @extensions = %w[js jsx]
89
94
  @dry_run = false
90
95
  @verbose = false
91
- @stdout_logging = true
96
+ @stdout_logging = false
92
97
  @external_providers = {}
93
98
  @external_roots = []
94
99
  end
@@ -12,7 +12,8 @@ module ReactManifest
12
12
  # Returns an array of result hashes:
13
13
  # [{path: "/abs/path/ux_shared.js", status: :written}, ...]
14
14
  #
15
- # Possible +status+ values: +:written+, +:unchanged+, +:skipped_pinned+, +:dry_run+.
15
+ # Possible +status+ values: +:written+, +:unchanged+, +:skipped_pinned+, +:dry_run+,
16
+ # +:removed_orphan+.
16
17
  #
17
18
  # Generates:
18
19
  # ux_shared.js — requires all files from shared dirs (components/, hooks/, lib/, etc.)
@@ -22,6 +23,9 @@ module ReactManifest
22
23
  # (skips write if content unchanged). Writes are atomic (temp-file + rename)
23
24
  # to avoid partial reads from concurrent processes.
24
25
  #
26
+ # Manifests whose ux/app/<controller> dir no longer exists are removed
27
+ # automatically (pinned files are never removed this way).
28
+ #
25
29
  # Never touches application.js, application_dev.js, or files in exclude_paths.
26
30
  # rubocop:disable Metrics/ClassLength
27
31
  class Generator
@@ -58,6 +62,12 @@ module ReactManifest
58
62
  # Phase 2: write — each write is atomic (tmp + rename).
59
63
  results = manifests.map { |m| write_manifest(m[:filename], m[:content]) }
60
64
 
65
+ # Phase 3: remove manifests left behind by a controller dir that no
66
+ # longer exists (renamed/deleted ux/app/<controller>). Never touches
67
+ # pinned (non-AUTO-GENERATED) files.
68
+ expected_filenames = manifests.map { |m| m[:filename] }
69
+ results.concat(remove_orphaned_manifests(expected_filenames))
70
+
61
71
  print_summary(results) if @config.verbose?
62
72
  results
63
73
  end
@@ -322,6 +332,25 @@ module ReactManifest
322
332
  end
323
333
  end
324
334
 
335
+ # Remove AUTO-GENERATED manifests that no longer correspond to any
336
+ # current shared/controller bundle (e.g. a ux/app/<controller> dir was
337
+ # deleted or renamed). Skips pinned files and, in dry-run mode, only
338
+ # logs what would be removed.
339
+ def remove_orphaned_manifests(expected_filenames)
340
+ Dir.glob(File.join(@config.abs_manifest_dir, "ux_*.js")).filter_map do |file|
341
+ next if expected_filenames.include?(File.basename(file))
342
+ next unless auto_generated?(file)
343
+
344
+ if @config.dry_run?
345
+ log_info "DRY-RUN: would remove orphaned manifest #{file}"
346
+ { path: file, status: :dry_run }
347
+ else
348
+ File.delete(file)
349
+ { path: file, status: :removed_orphan }
350
+ end
351
+ end
352
+ end
353
+
325
354
  # ----------------------------------------------------------- helpers
326
355
 
327
356
  def header_lines
@@ -433,7 +462,8 @@ module ReactManifest
433
462
  counts = results.group_by { |r| r[:status] }.transform_values(&:count)
434
463
  log_info "Generated: #{counts[:written] || 0} written, " \
435
464
  "#{counts[:unchanged] || 0} unchanged, " \
436
- "#{counts[:skipped_pinned] || 0} skipped (not auto-generated)"
465
+ "#{counts[:skipped_pinned] || 0} skipped (not auto-generated), " \
466
+ "#{counts[:removed_orphan] || 0} orphaned removed"
437
467
  end
438
468
  end
439
469
  # rubocop:enable Metrics/ClassLength
@@ -1,3 +1,3 @@
1
1
  module ReactManifest
2
- VERSION = "0.2.31".freeze
2
+ VERSION = "0.2.33".freeze
3
3
  end
@@ -91,6 +91,7 @@ module ReactManifest
91
91
  end
92
92
 
93
93
  (modified + added + removed).each { |f| Scanner.invalidate(f) }
94
+ ReactManifest.invalidate_component_maps!
94
95
  schedule_regeneration(config)
95
96
  end
96
97
 
@@ -35,6 +35,15 @@ module ReactManifest
35
35
  Scanner.clear_cache!
36
36
  end
37
37
 
38
+ # Drop the cached component-symbol -> bundle map used by
39
+ # resolve_bundle_for_component / resolve_bundles_for_component(_direct).
40
+ # Unlike reset!, this does NOT touch the current Configuration — safe to
41
+ # call whenever ux/ files change (e.g. from the file watcher) so newly
42
+ # added controllers/components are picked up without losing app config.
43
+ def invalidate_component_maps!
44
+ @component_maps_cache = nil
45
+ end
46
+
38
47
  # Returns the ordered list of bundle logical names for a given controller.
39
48
  # Used by the react_bundle_tag view helper.
40
49
  def resolve_bundles(ctrl_name)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: react-manifest-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.31
4
+ version: 0.2.33
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Noonan