react-manifest-rails 0.2.23 → 0.2.24

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: 907e5e7bb8b3e6a8554009c4e8a87a39379d8bd09c4455fd9c02b082a014c18b
4
- data.tar.gz: 11d4e6ca8833973107937eee1b82881f620f3b2e74442ab0883521ea5803d58b
3
+ metadata.gz: 786d53e91fe8a65339def86bc62a94179762364cf13d1abcc8427ea9585f0c38
4
+ data.tar.gz: 90c58cd92bc06eb2911deaf829aca60ed8533e6dc58e535759e9f6d60eefdcd2
5
5
  SHA512:
6
- metadata.gz: 950abc3b34f1ffe0e8eb6fcd4ae7798469b60746531d0bb0171de0975881cb2572f35182e07785255fcf932ce14ccaac369a1238e2d5e2fe3b8689d323861d06
7
- data.tar.gz: dc6fcbfb087a8aa9f95ff109147ee0345b2aa32fc1a0281118ffb60d12313735d659ecb55200832eb940bf6def8675ab711e64208fcc0ec17514e71e0ea57f42
6
+ metadata.gz: 30c7f0633646f06cfc497a617c76dbbb50f74e84104fd590f3054bff5c228a42e08aa6683dfdc96702656a52cec57533917b2438d4bb39ede667ef6c0686f219
7
+ data.tar.gz: 0ea044f3d55bb64be2ce9a725cc90cf9b33da8f343fde043707c098995ce6e88840e609947867203efe739623ce5dba3a32e4d444dfb9b3f8b252b56b991adbb
data/CHANGELOG.md CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.24] - 2026-04-22
11
+
12
+ ### Fixed
13
+ - Controller manifests now inline files from bundles listed in `always_include` (for example `ux_main`), so runtime symbol availability no longer depends on cross-bundle script execution order in production.
14
+ - Scanner analysis no longer emits warnings for ux/app file naming convention mismatches, reducing noise for apps that intentionally use custom filename patterns.
15
+
16
+ ### Changed
17
+ - Updated `Gemfile.lock` to keep lockfile state aligned with the released codebase.
18
+
10
19
  ## [0.2.23] - 2026-04-21
11
20
 
12
21
  ### Fixed
@@ -43,11 +43,11 @@ module ReactManifest
43
43
  def run!
44
44
  classification = @classifier.classify
45
45
  scan_result = Scanner.new(@config).scan(classification)
46
- controller_context = build_controller_context(classification.controller_dirs, classification.shared_dirs, scan_result)
46
+ controller_context = build_controller_context(classification.controller_dirs, classification.shared_dirs,
47
+ scan_result)
47
48
 
48
49
  # Phase 1: build all content in memory — no I/O.
49
- manifests = []
50
- classification.controller_dirs.each { |ctrl| manifests << build_controller(ctrl, controller_context) }
50
+ manifests = classification.controller_dirs.map { |ctrl| build_controller(ctrl, controller_context) }
51
51
 
52
52
  migrate_legacy_manifests!
53
53
 
@@ -62,12 +62,11 @@ module ReactManifest
62
62
 
63
63
  # ------------------------------------------------------------------ shared
64
64
 
65
-
66
-
67
65
  # --------------------------------------------------------------- controller
68
66
 
69
67
  def build_controller(ctrl, controller_context)
70
68
  lines = header_lines
69
+ always_include_reqs = controller_context[:always_include_requires].fetch(ctrl[:bundle_name], [])
71
70
  dep_requires = controller_dependency_requires(ctrl[:bundle_name], controller_context)
72
71
  lib_reqs = controller_context[:shared_lib_requires]
73
72
  shared_reqs = controller_context[:shared_requires].fetch(ctrl[:bundle_name], Set.new).to_a.sort
@@ -75,7 +74,7 @@ module ReactManifest
75
74
 
76
75
  files = js_files_in(ctrl[:path])
77
76
  own_requires = files.map { |f| relative_require_path(f) }
78
- all_requires = (dep_requires + lib_reqs + shared_reqs + ext_reqs + own_requires).uniq
77
+ all_requires = (always_include_reqs + dep_requires + lib_reqs + shared_reqs + ext_reqs + own_requires).uniq
79
78
 
80
79
  if all_requires.empty?
81
80
  lines << "// (no JSX files found in #{ctrl[:name]}/)"
@@ -86,6 +85,7 @@ module ReactManifest
86
85
  { filename: "#{ctrl[:bundle_name]}.js", content: "#{lines.join("\n")}\n" }
87
86
  end
88
87
 
88
+ # rubocop:disable Metrics/AbcSize
89
89
  def build_controller_context(controller_dirs, shared_dirs, scan_result)
90
90
  bundle_files = {}
91
91
  symbol_to_bundle = {}
@@ -103,10 +103,8 @@ module ReactManifest
103
103
  end
104
104
  shared_requires[ctrl[:bundle_name]] = expand_shared_requires(shared_requires[ctrl[:bundle_name]],
105
105
  shared_dependency_map)
106
- end
107
106
 
108
- # Index controller-defined symbols for cross-app detection
109
- controller_dirs.each do |ctrl|
107
+ # Index controller-defined symbols for cross-app detection
110
108
  bundle_name = ctrl[:bundle_name]
111
109
  files = js_files_in(ctrl[:path])
112
110
  bundle_files[bundle_name] = files
@@ -152,14 +150,18 @@ module ReactManifest
152
150
  end
153
151
  end
154
152
 
153
+ always_include_requires = build_always_include_requires(bundle_files, dependencies)
154
+
155
155
  {
156
156
  bundle_files: bundle_files,
157
157
  dependencies: dependencies,
158
+ always_include_requires: always_include_requires,
158
159
  shared_lib_requires: shared_lib_requires,
159
160
  shared_requires: shared_requires,
160
161
  external_requires: external_requires
161
162
  }
162
163
  end
164
+ # rubocop:enable Metrics/AbcSize
163
165
 
164
166
  def controller_dependency_requires(bundle_name, controller_context)
165
167
  deps = transitive_dependencies(bundle_name, controller_context[:dependencies])
@@ -189,6 +191,32 @@ module ReactManifest
189
191
  ordered
190
192
  end
191
193
 
194
+ def build_always_include_requires(bundle_files, dependencies)
195
+ bundles = @config.always_include.map(&:to_s).reject(&:empty?).uniq
196
+ return Hash.new { |h, k| h[k] = [] } if bundles.empty?
197
+
198
+ requires_by_bundle = Hash.new { |h, k| h[k] = [] }
199
+
200
+ bundle_files.each_key do |bundle_name|
201
+ requires = Set.new
202
+
203
+ bundles.each do |always_bundle|
204
+ next if always_bundle == bundle_name
205
+
206
+ transitive = [always_bundle] + transitive_dependencies(always_bundle, dependencies)
207
+ transitive.each do |dep_bundle|
208
+ bundle_files.fetch(dep_bundle, []).each do |abs_path|
209
+ requires << relative_require_path(abs_path)
210
+ end
211
+ end
212
+ end
213
+
214
+ requires_by_bundle[bundle_name] = requires.to_a.sort
215
+ end
216
+
217
+ requires_by_bundle
218
+ end
219
+
192
220
  # --------------------------------------------------------------- write
193
221
 
194
222
  def write_manifest(filename, content)
@@ -23,7 +23,7 @@ module ReactManifest
23
23
  /function\s+([A-Z][A-Za-z0-9_]*)\s*\(/, # function FooBar(
24
24
  /class\s+([A-Z][A-Za-z0-9_]*)\s*(?:extends|\{)/, # class FooBar
25
25
  /(?:const|let|var)\s+(use[A-Z][A-Za-z0-9_]*)\s*=/, # const useFoo = (hooks)
26
- /function\s+(use[A-Z][A-Za-z0-9_]*)\s*\(/, # function useFoo(
26
+ /function\s+(use[A-Z][A-Za-z0-9_]*)\s*\(/, # function useFoo(
27
27
 
28
28
  # ES module style (export default / named exports)
29
29
  /^export\s+default\s+(?:function|class)\s+([A-Z][A-Za-z0-9_]*)/,
@@ -130,7 +130,6 @@ module ReactManifest
130
130
  warnings.add("Controller dir '#{ctrl[:name]}' has no JS/JSX files") if files.empty? && @config.verbose?
131
131
 
132
132
  files.each do |file_path|
133
- validate_naming(file_path, ctrl[:name], warnings)
134
133
  content = read_controller_file(file_path, warnings)
135
134
  next unless content
136
135
 
@@ -191,15 +190,6 @@ module ReactManifest
191
190
  rel.sub(/\.js\.jsx$/, "").sub(/\.jsx$/, "").sub(/\.js$/, "")
192
191
  end
193
192
 
194
- def validate_naming(file_path, ctrl_name, warnings)
195
- basename = File.basename(file_path, ".*").sub(/\.js$/, "")
196
- # Expected: <controller>_index, <controller>_show, <controller>_form, etc.
197
- return if basename.start_with?("#{ctrl_name}_") || basename == ctrl_name
198
-
199
- warnings.add("File '#{File.basename(file_path)}' in '#{ctrl_name}' does not follow " \
200
- "'#{ctrl_name}_<action>.js.jsx' naming convention")
201
- end
202
-
203
193
  def detect_shared_violations(shared_file_paths, controller_symbol_index, warnings)
204
194
  violations = []
205
195
  shared_file_paths.each do |file_path, relative|
@@ -222,8 +212,8 @@ module ReactManifest
222
212
  violations << { shared_file: relative, symbol: sym,
223
213
  controller: info[:controller], app_file: info[:file] }
224
214
  warnings.add("Shared file '#{relative}' uses app-dir symbol '#{sym}' " \
225
- "(from ux/app/#{info[:controller]}). " \
226
- "Move '#{sym}' to a shared dir or the shared file will be incomplete.")
215
+ "(from ux/app/#{info[:controller]}). " \
216
+ "Move '#{sym}' to a shared dir or the shared file will be incomplete.")
227
217
  end
228
218
  end
229
219
  end
@@ -252,8 +242,8 @@ module ReactManifest
252
242
  violations << { external_file: relative, symbol: sym,
253
243
  controller: info[:controller], app_file: info[:file] }
254
244
  warnings.add("External file '#{relative}' uses app-dir symbol '#{sym}' " \
255
- "(from ux/app/#{info[:controller]}). " \
256
- "Move '#{sym}' into a shared ux dir to avoid duplicate runtime declarations.")
245
+ "(from ux/app/#{info[:controller]}). " \
246
+ "Move '#{sym}' into a shared ux dir to avoid duplicate runtime declarations.")
257
247
  end
258
248
  end
259
249
  end
@@ -268,9 +258,7 @@ module ReactManifest
268
258
  end
269
259
 
270
260
  fanout.each do |file, count|
271
- if count > 3
272
- warnings.add("High fan-out: '#{file}' is used by #{count} controllers")
273
- end
261
+ warnings.add("High fan-out: '#{file}' is used by #{count} controllers") if count > 3
274
262
  end
275
263
  end
276
264
 
@@ -1,3 +1,3 @@
1
1
  module ReactManifest
2
- VERSION = "0.2.23".freeze
2
+ VERSION = "0.2.24".freeze
3
3
  end
@@ -75,7 +75,7 @@ module ReactManifest
75
75
  if respond_to?(:request, true) && request
76
76
  request.env["react_manifest.emitted_bundles"] ||= []
77
77
  else
78
- @_react_manifest_emitted_bundles ||= []
78
+ @emitted_bundles ||= []
79
79
  end
80
80
  end
81
81
 
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.23
4
+ version: 0.2.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Noonan