proscenium 0.26.0-aarch64-linux-gnu → 0.27.0-aarch64-linux-gnu

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +50 -3
  3. data/lib/proscenium/app_package.rb +8 -4
  4. data/lib/proscenium/builder/request.rb +72 -0
  5. data/lib/proscenium/builder.rb +10 -74
  6. data/lib/proscenium/cli/bun_linker.rb +2 -2
  7. data/lib/proscenium/cli/collisions.rb +7 -9
  8. data/lib/proscenium/cli/error.rb +58 -265
  9. data/lib/proscenium/cli/gem_archive.rb +4 -2
  10. data/lib/proscenium/cli/gem_check.rb +13 -11
  11. data/lib/proscenium/cli/gitignore.rb +2 -1
  12. data/lib/proscenium/cli/inspect.rb +12 -11
  13. data/lib/proscenium/cli/install.rb +35 -46
  14. data/lib/proscenium/cli/manager.rb +6 -6
  15. data/lib/proscenium/cli/platform_variants.rb +8 -8
  16. data/lib/proscenium/cli/pnpm_approvals.rb +3 -3
  17. data/lib/proscenium/cli/pnpm_workspace.rb +15 -14
  18. data/lib/proscenium/cli/project_lock.rb +3 -3
  19. data/lib/proscenium/cli/registration.rb +5 -5
  20. data/lib/proscenium/cli/reporter.rb +2 -2
  21. data/lib/proscenium/cli/verify.rb +9 -50
  22. data/lib/proscenium/cli.rb +5 -4
  23. data/lib/proscenium/contexts/map.rb +183 -0
  24. data/lib/proscenium/contexts/mapping_generation.rb +68 -0
  25. data/lib/proscenium/contexts/messages.rb +276 -0
  26. data/lib/proscenium/{cli/contexts.rb → contexts/plan.rb} +12 -12
  27. data/lib/proscenium/contexts/projection.rb +77 -0
  28. data/lib/proscenium/{cli → contexts}/rules.rb +1 -1
  29. data/lib/proscenium/contexts/stale.rb +174 -0
  30. data/lib/proscenium/contexts.rb +16 -0
  31. data/lib/proscenium/css_module/path.rb +1 -0
  32. data/lib/proscenium/css_module/transformer.rb +15 -0
  33. data/lib/proscenium/css_module.rb +3 -2
  34. data/lib/proscenium/ext/proscenium +0 -0
  35. data/lib/proscenium/helper.rb +6 -1
  36. data/lib/proscenium/importer.rb +13 -1
  37. data/lib/proscenium/middleware/base.rb +0 -4
  38. data/lib/proscenium/middleware.rb +0 -2
  39. data/lib/proscenium/railtie.rb +4 -4
  40. data/lib/proscenium/resolver.rb +3 -1
  41. data/lib/proscenium/side_load.rb +6 -2
  42. data/lib/proscenium/source_path.rb +2 -0
  43. data/lib/proscenium/utils.rb +2 -1
  44. data/lib/proscenium/version.rb +1 -1
  45. data/lib/proscenium.rb +5 -5
  46. metadata +10 -7
  47. data/lib/proscenium/context_map.rb +0 -181
  48. data/lib/proscenium/dependency_context.rb +0 -74
  49. data/lib/proscenium/mapping_generation.rb +0 -64
  50. data/lib/proscenium/stale_contexts.rb +0 -118
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Proscenium
4
- module CLI
4
+ module Contexts
5
5
  # The author contract for a participating gem's package.json (#154): what `gem check` and
6
6
  # `install` refuse. Each rule yields a problem as [error code, format arguments]; the caller
7
7
  # decides whether a problem is fatal and how to word the escape.
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative '../app_package'
5
+ require_relative '../bundled_gems'
6
+ require_relative 'map'
7
+ require_relative 'projection'
8
+ require_relative 'plan'
9
+ require_relative 'messages'
10
+
11
+ module Proscenium
12
+ module Contexts
13
+ # Whether an adopted app's committed gem dependency contexts are what its bundle calls for
14
+ # (#154). A stale context resolves a gem's imports against the wrong dependency graph, so the
15
+ # engine refuses to build until `proscenium install` brings them up to date. Built from
16
+ # committed files and Bundler only. The engine and the CLI both load it, so it loads nothing
17
+ # the CLI may not, and nothing of cli/ (both directions are pinned by
18
+ # test/cli/load_isolation_test.rb).
19
+ module Stale
20
+ COMMAND = 'Run `bundle exec proscenium install` and commit .proscenium/packages.'
21
+ # Why a committed context is not the one install would write, by its `drift`. The engine,
22
+ # `install --frozen` and `inspect` all classify a context with `drift`, so they name one
23
+ # cause.
24
+ REASONS = {
25
+ missing: "its dependency context hasn't been written yet",
26
+ invalid: 'its dependency context is not valid JSON',
27
+ projection: 'its dependency context was written by a different version of Proscenium',
28
+ edited: 'its dependency context was edited by hand',
29
+ changed: 'its NPM dependencies changed since its dependency context was written'
30
+ }.freeze
31
+ ORPHAN = '%<gem>s: its dependency context is left over, as the gem is no longer in the ' \
32
+ 'bundle or no longer opted in'
33
+
34
+ module_function
35
+
36
+ # One line for each way the committed contexts differ from the bundle; empty when current, or
37
+ # before the app adopts. A context is stale when a participating gem has none, when its gem
38
+ # left Gemfile.lock or stopped participating, when its projection hash is not the gem's
39
+ # current one, or when that hash is not the one its own fields produce (a hand edit). A
40
+ # locked gem that is not installed (a group BUNDLE_WITHOUT excludes) keeps its context as
41
+ # committed.
42
+ def problems(root, specs = BundledGems.installed_specs, locked = BundledGems.locked_names)
43
+ registrar = Map.registrar(root)
44
+ return [] unless registrar
45
+
46
+ # Only the registration in use: a Bun app does not read a pnpm-workspace.yaml left over.
47
+ unparsable = unparsable_workspace(root) if registrar == 'pnpm-workspace.yaml'
48
+ return [unparsable] if unparsable
49
+
50
+ participating = BundledGems.participating(specs, overrides: BundledGems.overrides(root))
51
+ contexts = Plan.new(root, participating)
52
+ committed = Plan.committed(root)
53
+ found = contexts.problems.map { |code, args| Messages.message(code, **args) }
54
+ contexts.contexts.each_value do |context|
55
+ problem = compare(context, committed[context.gem])
56
+ found << "#{context.gem}: #{problem}" if problem
57
+ end
58
+ excluded = (locked || []) - specs.map(&:name)
59
+ orphans = committed.keys - participating.keys - excluded
60
+ found + orphans.map { format(ORPHAN, gem: it) } +
61
+ split_peers(root, contexts.contexts.keys & committed.keys)
62
+ rescue BundledGems::ConfigError => e
63
+ [e.message]
64
+ end
65
+
66
+ # An app counts as adopted when a pnpm-workspace.yaml it cannot parse names the contexts, so
67
+ # the engine never silently switches them off; it refuses until the file parses. Not
68
+ # package.json: Bun reads JSON that Ruby refuses, such as a trailing comma.
69
+ def unparsable_workspace(root)
70
+ path = File.join(root, 'pnpm-workspace.yaml')
71
+ return unless File.exist?(path)
72
+
73
+ Map.yaml_packages(Map.utf8(File.read(path)).delete_prefix(Map::BOM))
74
+ nil
75
+ rescue Psych::SyntaxError => e
76
+ "pnpm-workspace.yaml: it is not valid YAML (#{e.problem} at line #{e.line})"
77
+ end
78
+
79
+ # A peer meant to be shared that the gem and the app reach as two copies, as an app-only
80
+ # `pnpm update react` can leave it: install checks this too, and the engine repeats it for
81
+ # each generation.
82
+ def split_peers(root, gems)
83
+ gem, package = peer_split(root, gems)
84
+ gem ? [Messages.message('PSM-E-PEER-SPLIT', gem:, package:)] : []
85
+ end
86
+
87
+ # The first `[gem, package]` where a peer a context declares, that the app also depends on,
88
+ # resolves from the context and from the app to two different real directories; nil when
89
+ # every one is a single copy. A context that is missing or not valid JSON has no peers to
90
+ # check: `problems` and `install --frozen` report it themselves.
91
+ def peer_split(root, gems)
92
+ app = app_dependencies(root)
93
+ gems.each do |gem|
94
+ dir = File.join(root, Map::CONTEXTS, gem)
95
+ (peers(dir).keys & app).each do |name|
96
+ from_gem = real_dependency_dir(root, dir, name)
97
+ from_app = real_dependency_dir(root, root, name)
98
+ return [gem, name] unless from_gem.nil? || from_app.nil? || from_gem == from_app
99
+ end
100
+ end
101
+ nil
102
+ end
103
+
104
+ def peers(dir)
105
+ context = Map.read_json(File.join(dir, 'package.json'))
106
+ peers = context['peerDependencies'] if context.is_a?(Hash)
107
+ peers.is_a?(Hash) ? peers : {}
108
+ rescue Errno::ENOENT, JSON::ParserError
109
+ {}
110
+ end
111
+
112
+ def app_dependencies(root)
113
+ package = Map.read_json(File.join(root, 'package.json'))
114
+ return [] unless package.is_a?(Hash)
115
+
116
+ AppPackage::DEPENDENCY_FIELDS.flat_map { package[it].is_a?(Hash) ? package[it].keys : [] }
117
+ rescue Errno::ENOENT, JSON::ParserError
118
+ []
119
+ end
120
+
121
+ # The real directory `name` resolves to from `dir`, walking up node_modules as Node does,
122
+ # but no higher than the app at `root`.
123
+ def real_dependency_dir(root, dir, name)
124
+ current = dir
125
+ loop do
126
+ candidate = File.join(current, 'node_modules', name)
127
+ return File.realpath(candidate) if File.exist?(candidate)
128
+ return nil if current == root || current == File.dirname(current)
129
+
130
+ current = File.dirname(current)
131
+ end
132
+ end
133
+
134
+ # Why the engine refuses the committed context at `path`, or nil when it builds with it.
135
+ def compare(context, path) = REASONS[drift(context, path)]
136
+
137
+ # How the committed context at `path` differs from `context`, as a key of REASONS, or nil
138
+ # when it holds the same JSON. It is projected again from the fields it holds, not taken on
139
+ # trust: a hand edit that kept the reported hash would build against a graph no install
140
+ # produced.
141
+ def drift(context, path)
142
+ return :missing unless path && File.exist?(path)
143
+
144
+ committed = Map.read_json(path)
145
+ return :invalid unless committed.is_a?(Hash) && committed['proscenium'].is_a?(Hash)
146
+ return :projection if committed['proscenium']['projection'] != Projection::PROJECTION
147
+
148
+ # Parsed, so reformatting is not an edit; whole, so its name and the other generated fields
149
+ # count as well as its hash.
150
+ return :edited if Projection.project(context.gem, committed) != committed
151
+
152
+ :changed unless committed == JSON.parse(context.json)
153
+ rescue JSON::ParserError
154
+ :invalid
155
+ end
156
+
157
+ # The build error for the app at `root`, or nil when its contexts are current. Read once per
158
+ # mapping generation, as Map.config is.
159
+ def message(root, generation = 0)
160
+ @message ||= {}
161
+ key = [root, generation]
162
+ return @message[key] if @message.key?(key)
163
+
164
+ found = problems(root)
165
+ @message[key] = if found.any?
166
+ "Gem dependency contexts are out of date:\n" \
167
+ "#{found.map { " - #{it}" }.join("\n")}\n#{COMMAND}"
168
+ end
169
+ end
170
+
171
+ def reset! = @message = {}
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Proscenium
4
+ # The model of gem dependency contexts (#154), which the engine and the `proscenium` CLI share.
5
+ # Its files load nothing of either: not ActiveSupport, and nothing under cli/. The CLI requires
6
+ # each file it needs; the engine reaches them through these autoloads.
7
+ module Contexts
8
+ autoload :Map, "#{__dir__}/contexts/map"
9
+ autoload :MappingGeneration, "#{__dir__}/contexts/mapping_generation"
10
+ autoload :Messages, "#{__dir__}/contexts/messages"
11
+ autoload :Plan, "#{__dir__}/contexts/plan"
12
+ autoload :Projection, "#{__dir__}/contexts/projection"
13
+ autoload :Rules, "#{__dir__}/contexts/rules"
14
+ autoload :Stale, "#{__dir__}/contexts/stale"
15
+ end
16
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Proscenium
4
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
4
5
  module CssModule::Path
5
6
  # Returns the path to the CSS module file for this class, where the file is located alongside
6
7
  # the class file, and has the same name as the class file, but with a `.module.css` extension.
@@ -55,6 +55,8 @@ module Proscenium
55
55
  # @yieldparam transformed_name [String]
56
56
  # @yieldparam side_load_path [String, nil]
57
57
  # @return [Array<String>] the transformed CSS module names.
58
+ #
59
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
58
60
  def class_names(*names, require_prefix: true)
59
61
  self.class.filter_names(names).map do |name|
60
62
  transformed, path = transform_class_name(name, require_prefix: require_prefix)
@@ -63,6 +65,19 @@ module Proscenium
63
65
  end
64
66
  end
65
67
 
68
+ # Transforms one class `name` to its CSS module name against the CSS module at `path`, whatever
69
+ # its prefix, and side loads that module. `original_name` is the name as the caller wrote it,
70
+ # for the error raised when there is no path.
71
+ #
72
+ # transformer.class_name!(:title, 'cssm:title') # => "title_<digest>"
73
+ #
74
+ # @param name [String, Symbol]
75
+ # @param original_name [String]
76
+ # @param path [Pathname, String] the CSS module; by default, the transformer's own.
77
+ # @raise [Proscenium::CssModule::TransformError] when there is no path.
78
+ # @return [String] the transformed CSS module name.
79
+ #
80
+ # @api public: apps call it directly (README, "Extending Proscenium").
66
81
  def class_name!(name, original_name, path: @source_path)
67
82
  unless path
68
83
  raise Proscenium::CssModule::TransformError.new(original_name, 'CSS module path not given')
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
3
4
  module Proscenium::CssModule
4
5
  extend ActiveSupport::Autoload
5
6
 
@@ -17,14 +18,14 @@ module Proscenium::CssModule
17
18
 
18
19
  module ClassMethods
19
20
  def css_module(*names, path: nil)
20
- path ||= respond_to?(:css_module_path) ? css_module_path : path
21
+ path ||= css_module_path if respond_to?(:css_module_path)
21
22
 
22
23
  cssm = Transformer.new(path)
23
24
  cssm.class_names(*names, require_prefix: false).join(' ')
24
25
  end
25
26
 
26
27
  def class_names(*names, path: nil)
27
- path ||= respond_to?(:css_module_path) ? css_module_path : path
28
+ path ||= css_module_path if respond_to?(:css_module_path)
28
29
  names = Transformer.filter_names(names)
29
30
 
30
31
  cssm = Transformer.new(path)
Binary file
@@ -45,9 +45,14 @@ module Proscenium
45
45
  @proscenium_sideload_assets_options ||= {}
46
46
  end
47
47
 
48
+ # A tag helper's source with no leading slash, looked up in the manifest's own key space:
49
+ # `/app/...` for an app file, `@rubygems/...` for a gem's. An entry holds its outputs, the
50
+ # entry's own first. With no entry, the URL the middleware serves it at, as Resolver builds it.
48
51
  def compute_asset_path(path, options = {})
49
52
  if %i[javascript stylesheet].include?(options[:type])
50
- return Proscenium::Manifest[path] || "/#{path}"
53
+ gem = path.start_with?('@rubygems/')
54
+ return Proscenium::Manifest[gem ? path : "/#{path}"]&.first ||
55
+ (gem ? "/node_modules/#{path}" : "/#{path}")
51
56
  end
52
57
 
53
58
  super
@@ -32,7 +32,9 @@ module Proscenium
32
32
  # or a URL, which has no file on disk. Should be the actual asset file, eg. app.css,
33
33
  # some/component.js.
34
34
  # @return [String|nil] the digest of the imported file path if a css module (*.module.css).
35
- def import(filepath = nil, sideloaded: false, **)
35
+ #
36
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
37
+ def import(filepath, sideloaded: false, **)
36
38
  self.imported ||= {}
37
39
 
38
40
  if filepath.end_with?('.module.css')
@@ -90,6 +92,8 @@ module Proscenium
90
92
  #
91
93
  # @param filepath [Pathname] Absolute file system path of the Ruby file to sideload.
92
94
  # @param options [Hash] Options to pass to `import`.
95
+ #
96
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
93
97
  def sideload(filepath, **options)
94
98
  return if !Proscenium.config.side_load || (options[:js] == false && options[:css] == false)
95
99
 
@@ -129,6 +133,10 @@ module Proscenium
129
133
  end
130
134
  end
131
135
 
136
+ # Yields each imported stylesheet, with its options. `delete: true` also removes each one from
137
+ # the imports, so it is written only once.
138
+ #
139
+ # @api public: apps call it to write their own tags (README, "Extending Proscenium").
132
140
  def each_stylesheet(delete: false)
133
141
  return if imported.blank?
134
142
 
@@ -142,6 +150,10 @@ module Proscenium
142
150
  delete ? imported.delete_if(&blk) : imported.each(&blk)
143
151
  end
144
152
 
153
+ # Yields each imported script, with its options. `delete: true` also removes each one from the
154
+ # imports, so it is written only once.
155
+ #
156
+ # @api public: apps call it to write their own tags (README, "Extending Proscenium").
145
157
  def each_javascript(delete: false)
146
158
  return if imported.blank?
147
159
 
@@ -3,8 +3,6 @@
3
3
  module Proscenium
4
4
  class Middleware
5
5
  class Base
6
- include ActiveSupport::Benchmarkable
7
-
8
6
  def self.attempt(request)
9
7
  new(request).renderable!&.attempt
10
8
  end
@@ -70,8 +68,6 @@ module Proscenium
70
68
  when '.js', '.mjs', '.ts', '.tsx', '.jsx' then 'application/javascript'
71
69
  when '.css' then 'text/css'
72
70
  when '.map' then 'application/json'
73
- else
74
- ::Rack::Mime.mime_type(::File.extname(path_to_build), nil) || 'application/javascript'
75
71
  end
76
72
  end
77
73
 
@@ -4,8 +4,6 @@ module Proscenium
4
4
  class Middleware
5
5
  extend ActiveSupport::Autoload
6
6
 
7
- class BuildError < Error; end
8
-
9
7
  autoload :Base
10
8
  autoload :Esbuild
11
9
  autoload :RubyGems
@@ -36,16 +36,16 @@ module Proscenium
36
36
 
37
37
  Proscenium::Manifest.load!
38
38
 
39
- project = Proscenium::ContextMap.project_root
40
- if (notice = Proscenium::ContextMap.adoption_notice(project))
39
+ project = Proscenium::Contexts::Map.project_root
40
+ if (notice = Proscenium::Contexts::Map.adoption_notice(project))
41
41
  Rails.logger.info "[Proscenium] #{notice}"
42
42
  end
43
43
  # Production finds stale contexts at assets:precompile, which refuses to compile. Elsewhere
44
44
  # the first mapping generation starts here, so a change after boot, such as running
45
45
  # `proscenium install`, starts the next one. No Go call: Puma may fork after boot.
46
46
  unless Rails.env.production?
47
- generation, = Proscenium::MappingGeneration.refresh(project)
48
- if (stale = Proscenium::StaleContexts.message(project, generation))
47
+ generation, = Proscenium::Contexts::MappingGeneration.refresh(project)
48
+ if (stale = Proscenium::Contexts::Stale.message(project, generation))
49
49
  Rails.logger.warn "[Proscenium] #{stale}"
50
50
  end
51
51
  end
@@ -10,6 +10,8 @@ module Proscenium
10
10
  # @param as_array [Boolean] whether or not to return the manifest path, non-manifest path, and
11
11
  # absolute file system path as an array. Only returns the resolved path if false (default).
12
12
  # @return [String, Array<String>]
13
+ #
14
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
13
15
  def self.resolve(path, as_array: false)
14
16
  # Normalised before anything reads it, the guard and the cache key included. The bun test
15
17
  # harness hands this Bun's own spelling of a module path, which on Windows is `D:\...`;
@@ -55,7 +57,7 @@ module Proscenium
55
57
  def self.generation
56
58
  return 0 if Rails.env.production?
57
59
 
58
- number, changed = MappingGeneration.refresh(ContextMap.project_root)
60
+ number, changed = Contexts::MappingGeneration.refresh(Contexts::Map.project_root)
59
61
  reset if changed
60
62
  number
61
63
  end
@@ -38,7 +38,7 @@ module Proscenium
38
38
  opts = opts.merge(data: opts[:data] || {})
39
39
  opts = opts.merge(preload_links_header: false) if fragments
40
40
 
41
- out << helpers.stylesheet_link_tag(path.delete_prefix('/'), extname: false, **opts)
41
+ out << helpers.stylesheet_link_tag(path, extname: false, **opts)
42
42
  end
43
43
 
44
44
  if fragments
@@ -64,7 +64,7 @@ module Proscenium
64
64
  opts = opts[:js].is_a?(Hash) ? opts[:js] : {}
65
65
  opts = opts.merge(preload_links_header: false) if fragments
66
66
 
67
- out << helpers.javascript_include_tag(path.delete_prefix('/'), extname: false, **opts)
67
+ out << helpers.javascript_include_tag(path, extname: false, **opts)
68
68
  end
69
69
 
70
70
  if fragments
@@ -95,6 +95,8 @@ module Proscenium
95
95
  #
96
96
  # If the class responds to `.sideload`, it will be called after the regular side loading. You
97
97
  # can use this to customise what is side loaded.
98
+ #
99
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
98
100
  def sideload_inheritance_chain(obj, options)
99
101
  return unless Proscenium.config.side_load
100
102
 
@@ -168,6 +170,8 @@ module Proscenium
168
170
  # attribute, so writing to it would leak one request's options into every later one. Values
169
171
  # other than hashes are passed through as they are, not copied: `dup` on an ActiveRecord
170
172
  # model returns a new record with no id.
173
+ #
174
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
171
175
  def merge_options(base, override, receiver)
172
176
  options = base.nil? ? {} : base
173
177
  options = { js: options, css: options } unless options.is_a?(Hash)
@@ -2,6 +2,8 @@
2
2
 
3
3
  # Include this into any class to expose a `source_path` class and instance method, which will return
4
4
  # the absolute file system path to the current object.
5
+ #
6
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
5
7
  module Proscenium::SourcePath
6
8
  def self.included(base)
7
9
  base.extend ClassMethods
@@ -79,7 +79,7 @@ module Proscenium
79
79
  # Example:
80
80
  #
81
81
  # def tab(name, *args, href:, **attributes)
82
- # Hue::Utils.merge_bang_attributes!(args, attributes, [:current])
82
+ # UiGem::Utils.merge_bang_attributes!(args, attributes, [:current])
83
83
  # end
84
84
  #
85
85
  # Allowing you to use either of the following API's:
@@ -87,6 +87,7 @@ module Proscenium
87
87
  # tab 'Tab 1', required: true
88
88
  # tab 'Tab 1', :required!
89
89
  #
90
+ # @api public: an extension point for component gems (README, "Extending Proscenium").
90
91
  def merge_bang_attributes!(names, kw_attributes, allowed)
91
92
  allowed.each do |name|
92
93
  sym_name = name.to_sym
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Proscenium
4
- VERSION = '0.26.0'
4
+ VERSION = '0.27.0'
5
5
  end
data/lib/proscenium.rb CHANGED
@@ -2,12 +2,15 @@
2
2
 
3
3
  require 'active_support'
4
4
  require_relative 'proscenium/error'
5
+ # Required rather than autoloaded: the model's files are also required directly (by the CLI), and
6
+ # one that defined Contexts first would leave its autoloads unregistered.
7
+ require_relative 'proscenium/contexts'
5
8
 
6
9
  module Proscenium
7
10
  extend ActiveSupport::Autoload
8
11
 
9
- # Default paths for Rails assets. Used by the `compute_asset_path` helper to maintain Rails
10
- # default conventions of where JS and CSS files are located.
12
+ # Rails' default asset directories. Nothing in Proscenium reads this; it is public, and its
13
+ # removal waits on a release note (H-3 in docs/AUDIT.md, closed as not planned in #92).
11
14
  DEFAULT_RAILS_ASSET_PATHS = {
12
15
  stylesheet: 'app/assets/stylesheets/',
13
16
  javascript: 'app/javascript/'
@@ -39,9 +42,6 @@ module Proscenium
39
42
  autoload :Importer
40
43
  autoload :Resolver
41
44
  autoload :BundledGems
42
- autoload :ContextMap
43
- autoload :StaleContexts
44
- autoload :MappingGeneration
45
45
 
46
46
  class Deprecator
47
47
  def deprecation_warning(name, message, _caller_backtrace = nil)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proscenium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.0
4
+ version: 0.27.0
5
5
  platform: aarch64-linux-gnu
6
6
  authors:
7
7
  - Joel Moss
@@ -61,13 +61,13 @@ files:
61
61
  - lib/proscenium.rb
62
62
  - lib/proscenium/app_package.rb
63
63
  - lib/proscenium/builder.rb
64
+ - lib/proscenium/builder/request.rb
64
65
  - lib/proscenium/bundled_gems.rb
65
66
  - lib/proscenium/cli.rb
66
67
  - lib/proscenium/cli/brackets.rb
67
68
  - lib/proscenium/cli/bun_linker.rb
68
69
  - lib/proscenium/cli/capabilities.json
69
70
  - lib/proscenium/cli/collisions.rb
70
- - lib/proscenium/cli/contexts.rb
71
71
  - lib/proscenium/cli/diff.rb
72
72
  - lib/proscenium/cli/error.rb
73
73
  - lib/proscenium/cli/gem_archive.rb
@@ -82,14 +82,19 @@ files:
82
82
  - lib/proscenium/cli/project_lock.rb
83
83
  - lib/proscenium/cli/registration.rb
84
84
  - lib/proscenium/cli/reporter.rb
85
- - lib/proscenium/cli/rules.rb
86
85
  - lib/proscenium/cli/runner.rb
87
86
  - lib/proscenium/cli/verify.rb
88
- - lib/proscenium/context_map.rb
87
+ - lib/proscenium/contexts.rb
88
+ - lib/proscenium/contexts/map.rb
89
+ - lib/proscenium/contexts/mapping_generation.rb
90
+ - lib/proscenium/contexts/messages.rb
91
+ - lib/proscenium/contexts/plan.rb
92
+ - lib/proscenium/contexts/projection.rb
93
+ - lib/proscenium/contexts/rules.rb
94
+ - lib/proscenium/contexts/stale.rb
89
95
  - lib/proscenium/css_module.rb
90
96
  - lib/proscenium/css_module/path.rb
91
97
  - lib/proscenium/css_module/transformer.rb
92
- - lib/proscenium/dependency_context.rb
93
98
  - lib/proscenium/ensure_loaded.rb
94
99
  - lib/proscenium/error.rb
95
100
  - lib/proscenium/ext/proscenium
@@ -98,7 +103,6 @@ files:
98
103
  - lib/proscenium/importer.rb
99
104
  - lib/proscenium/log_subscriber.rb
100
105
  - lib/proscenium/manifest.rb
101
- - lib/proscenium/mapping_generation.rb
102
106
  - lib/proscenium/middleware.rb
103
107
  - lib/proscenium/middleware/base.rb
104
108
  - lib/proscenium/middleware/chunks.rb
@@ -115,7 +119,6 @@ files:
115
119
  - lib/proscenium/runtime/server.rb
116
120
  - lib/proscenium/side_load.rb
117
121
  - lib/proscenium/source_path.rb
118
- - lib/proscenium/stale_contexts.rb
119
122
  - lib/proscenium/templates/rescues/build_error.html.erb
120
123
  - lib/proscenium/utils.rb
121
124
  - lib/proscenium/version.rb