proscenium 0.18.0-aarch64-linux → 0.19.0-aarch64-linux

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -174
  3. data/lib/proscenium/builder.rb +36 -100
  4. data/lib/proscenium/bundled_gems.rb +37 -0
  5. data/lib/proscenium/css_module/path.rb +2 -1
  6. data/lib/proscenium/css_module/transformer.rb +1 -1
  7. data/lib/proscenium/css_module.rb +16 -9
  8. data/lib/proscenium/ensure_loaded.rb +14 -10
  9. data/lib/proscenium/ext/proscenium +0 -0
  10. data/lib/proscenium/ext/proscenium.h +9 -36
  11. data/lib/proscenium/helper.rb +4 -22
  12. data/lib/proscenium/importer.rb +39 -21
  13. data/lib/proscenium/log_subscriber.rb +11 -10
  14. data/lib/proscenium/middleware/base.rb +11 -6
  15. data/lib/proscenium/middleware/esbuild.rb +8 -9
  16. data/lib/proscenium/middleware/ruby_gems.rb +23 -0
  17. data/lib/proscenium/middleware.rb +26 -24
  18. data/lib/proscenium/monkey.rb +5 -14
  19. data/lib/proscenium/railtie.rb +11 -53
  20. data/lib/proscenium/{libs/react-manager → react-manager}/index.jsx +3 -22
  21. data/lib/proscenium/react_componentable.rb +2 -3
  22. data/lib/proscenium/resolver.rb +14 -23
  23. data/lib/proscenium/side_load.rb +41 -74
  24. data/lib/proscenium/utils.rb +33 -0
  25. data/lib/proscenium/version.rb +1 -1
  26. data/lib/proscenium.rb +2 -12
  27. metadata +11 -99
  28. data/lib/proscenium/core_ext/object/css_module_ivars.rb +0 -19
  29. data/lib/proscenium/css_module/rewriter.rb +0 -44
  30. data/lib/proscenium/libs/custom_element.js +0 -54
  31. data/lib/proscenium/libs/stimulus-loading.js +0 -65
  32. data/lib/proscenium/libs/test.js +0 -1
  33. data/lib/proscenium/libs/ujs/class.js +0 -15
  34. data/lib/proscenium/libs/ujs/data_confirm.js +0 -23
  35. data/lib/proscenium/libs/ujs/data_disable_with.js +0 -68
  36. data/lib/proscenium/libs/ujs/index.js +0 -9
  37. data/lib/proscenium/middleware/engines.rb +0 -45
  38. data/lib/proscenium/middleware/runtime.rb +0 -18
  39. data/lib/proscenium/phlex/asset_inclusions.rb +0 -17
  40. data/lib/proscenium/phlex/css_modules.rb +0 -79
  41. data/lib/proscenium/phlex/react_component.rb +0 -32
  42. data/lib/proscenium/phlex.rb +0 -42
  43. data/lib/proscenium/ui/breadcrumbs/component.module.css +0 -14
  44. data/lib/proscenium/ui/breadcrumbs/component.rb +0 -73
  45. data/lib/proscenium/ui/breadcrumbs/computed_element.rb +0 -69
  46. data/lib/proscenium/ui/breadcrumbs/control.rb +0 -95
  47. data/lib/proscenium/ui/breadcrumbs/mixins.css +0 -83
  48. data/lib/proscenium/ui/breadcrumbs.rb +0 -72
  49. data/lib/proscenium/ui/component.rb +0 -7
  50. data/lib/proscenium/ui/test.js +0 -1
  51. data/lib/proscenium/ui.rb +0 -8
  52. data/lib/proscenium/view_component/css_modules.rb +0 -11
  53. data/lib/proscenium/view_component/react_component.rb +0 -22
  54. data/lib/proscenium/view_component/sideload.rb +0 -4
  55. data/lib/proscenium/view_component.rb +0 -38
  56. /data/lib/proscenium/{libs/react-manager → react-manager}/react.js +0 -0
@@ -24,6 +24,7 @@ typedef struct { const char *p; ptrdiff_t n; } _GoString_;
24
24
  struct Result {
25
25
  int success;
26
26
  char* response;
27
+ char* contentHash;
27
28
  };
28
29
 
29
30
  #line 1 "cgo-generated-wrapper"
@@ -82,49 +83,21 @@ typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
82
83
  extern "C" {
83
84
  #endif
84
85
 
86
+ extern void reset_config();
85
87
 
86
- // Build the given `path` in the `root`.
88
+ // Build the given `path` using the `config`.
87
89
  //
88
- // BuildOptions
89
- // - path - The path to build relative to `root`.
90
- // - baseUrl - base URL of the Rails app. eg. https://example.com
91
- // - importMap - Path to the import map relative to `root`.
92
- // - envVars - JSON string of environment variables.
93
- // Config:
94
- // - root - The working directory.
95
- // - env - The environment (1 = development, 2 = test, 3 = production)
96
- // - codeSpitting?
97
- // - debug?
90
+ // - path - The path to build relative to `root`.
91
+ // - config
98
92
  //
99
- extern struct Result build_to_string(char* filepath, char* baseUrl, char* importMap, char* envVars, char* appRoot, char* gemPath, unsigned int env, GoUint8 codeSplitting, char* engines, GoUint8 debug);
100
-
101
- // Build the given `path` in the `root`.
102
- //
103
- // BuildOptions
104
- // - path - The path to build relative to `root`. Multiple paths can be given by separating them
105
- // with a semi-colon.
106
- // - baseUrl - base URL of the Rails app. eg. https://example.com
107
- // - importMap - Path to the import map relative to `root`.
108
- // - envVars - JSON string of environment variables.
109
- // Config:
110
- // - root - The working directory.
111
- // - env - The environment (1 = development, 2 = test, 3 = production)
112
- // - codeSpitting?
113
- // - debug?
114
- //
115
- extern struct Result build_to_path(char* filepath, char* baseUrl, char* importMap, char* envVars, char* appRoot, char* gemPath, unsigned int env, GoUint8 codeSplitting, char* engines, GoUint8 debug);
93
+ extern struct Result build_to_string(char* filePath, char* configJson);
116
94
 
117
95
  // Resolve the given `path` relative to the `root`.
118
96
  //
119
- // ResolveOptions
120
- // - path - The path to build relative to `root`.
121
- // - importMap - Path to the import map relative to `root`.
122
- // Config
123
- // - root - The working directory.
124
- // - env - The environment (1 = development, 2 = test, 3 = production)
125
- // - debug?
97
+ // - path - The path to build relative to `root`.
98
+ // - config
126
99
  //
127
- extern struct Result resolve(char* path, char* importMap, char* appRoot, char* gemPath, unsigned int env, GoUint8 debug);
100
+ extern struct Result resolve(char* filePath, char* configJson);
128
101
 
129
102
  #ifdef __cplusplus
130
103
  }
@@ -16,15 +16,13 @@ module Proscenium
16
16
  # those asset paths all begin with a slash, which the Rails asset helpers do not pass through to
17
17
  # here.
18
18
  #
19
- # If the given `path` is a bare path (does not start with `/` or `./` or `../`), then we use
19
+ # If the given `path` is a bare path (does not start with `./` or `../`), then we use
20
20
  # Rails default conventions, and serve CSS from /app/assets/stylesheets and JS from
21
21
  # /app/javascript.
22
22
  def compute_asset_path(path, options = {})
23
23
  if %i[javascript stylesheet].include?(options[:type])
24
- path.prepend DEFAULT_RAILS_ASSET_PATHS[options[:type]] unless path.start_with?('./', '../')
25
-
26
- result = Proscenium::Builder.build_to_path(path, base_url: request.base_url)
27
- return result.split('::').last.delete_prefix 'public'
24
+ path.prepend DEFAULT_RAILS_ASSET_PATHS[options[:type]] if !path.start_with?('./', '../')
25
+ return path
28
26
  end
29
27
 
30
28
  super
@@ -42,18 +40,6 @@ module Proscenium
42
40
  .map { |name, _| name }.join(' ')
43
41
  end
44
42
 
45
- # @param name [String,Symbol,Array<String,Symbol>]
46
- # @param path [Pathname] the path to the CSS file to use for the transformation.
47
- # @return [String] the transformed CSS module names concatenated as a string.
48
- def class_names(*names, path: nil)
49
- names = names.flatten.compact
50
-
51
- return if names.empty?
52
-
53
- path ||= Pathname.new(@lookup_context.find(@virtual_path).identifier).sub_ext('')
54
- CssModule::Transformer.new(path).class_names(*names).map { |name, _| name }.join(' ')
55
- end
56
-
57
43
  def include_assets
58
44
  include_stylesheets + include_javascripts
59
45
  end
@@ -61,16 +47,12 @@ module Proscenium
61
47
  def include_stylesheets
62
48
  SideLoad::CSS_COMMENT.html_safe
63
49
  end
64
- alias side_load_stylesheets include_stylesheets
65
- deprecate side_load_stylesheets: 'Use `include_stylesheets` instead', deprecator: Deprecator.new
66
50
 
67
51
  # Includes all javascripts that have been imported and side loaded.
68
52
  #
69
53
  # @return [String] the HTML tags for the javascripts.
70
54
  def include_javascripts
71
- (SideLoad::LAZY_COMMENT + SideLoad::JS_COMMENT).html_safe
55
+ SideLoad::JS_COMMENT.html_safe
72
56
  end
73
- alias side_load_javascripts include_javascripts
74
- deprecate side_load_javascripts: 'Use `include_javascripts` instead', deprecator: Deprecator.new
75
57
  end
76
58
  end
@@ -23,19 +23,24 @@ module Proscenium
23
23
  #
24
24
  # @param filepath [String] Absolute URL path (relative to Rails root) of the file to import.
25
25
  # Should be the actual asset file, eg. app.css, some/component.js.
26
- # @param resolve [String] description of the file to resolve and import.
27
- # @return [String] the digest of the imported file path if a css module (*.module.css).
28
- def import(filepath = nil, resolve: nil, **)
26
+ # @return [String|nil] the digest of the imported file path if a css module (*.module.css).
27
+ def import(filepath = nil, sideloaded: false, **)
29
28
  self.imported ||= {}
30
29
 
31
- filepath = Resolver.resolve(resolve) if !filepath && resolve
30
+ filepath = "/node_modules/#{filepath}" if filepath.start_with?('@rubygems/')
32
31
  css_module = filepath.end_with?('.module.css')
33
32
 
34
33
  unless self.imported.key?(filepath)
35
- # ActiveSupport::Notifications.instrument('sideload.proscenium', identifier: value)
36
-
37
- self.imported[filepath] = { ** }
38
- self.imported[filepath][:digest] = Utils.digest(filepath) if css_module
34
+ if sideloaded
35
+ ActiveSupport::Notifications.instrument 'sideload.proscenium', identifier: filepath,
36
+ sideloaded: do
37
+ self.imported[filepath] = { ** }
38
+ self.imported[filepath][:digest] = Utils.digest(filepath) if css_module
39
+ end
40
+ else
41
+ self.imported[filepath] = { ** }
42
+ self.imported[filepath][:digest] = Utils.digest(filepath) if css_module
43
+ end
39
44
  end
40
45
 
41
46
  css_module ? self.imported[filepath][:digest] : nil
@@ -60,6 +65,7 @@ module Proscenium
60
65
  # `.tsx` extension is matched first.
61
66
  #
62
67
  # @param filepath [Pathname] Absolute file system path of the Ruby file to sideload.
68
+ # @param options [Hash] Options to pass to `import`.
63
69
  def sideload(filepath, **options)
64
70
  return if !Proscenium.config.side_load || (options[:js] == false && options[:css] == false)
65
71
 
@@ -67,30 +73,42 @@ module Proscenium
67
73
  sideload_css(filepath, **options) unless options[:css] == false
68
74
  end
69
75
 
70
- def sideload_js(filepath, **options)
71
- return unless Proscenium.config.side_load
76
+ def sideload_js(filepath, **)
77
+ _sideload(filepath, JS_EXTENSIONS, **)
78
+ end
72
79
 
73
- filepath = Rails.root.join(filepath) unless filepath.is_a?(Pathname)
74
- filepath = filepath.sub_ext('')
80
+ def sideload_css(filepath, **)
81
+ _sideload(filepath, ['.css'], **)
82
+ end
75
83
 
76
- JS_EXTENSIONS.find do |x|
77
- if (fp = filepath.sub_ext(x)).exist?
78
- import(Resolver.resolve(fp.to_s), sideloaded: true, **options)
79
- end
80
- end
84
+ def sideload_css_module(filepath, **)
85
+ _sideload(filepath, ['.module.css'], **)
81
86
  end
82
87
 
83
- def sideload_css(filepath, **options)
88
+ # @param filepath [Pathname] Absolute file system path of the Ruby file to sideload.
89
+ # @param extensions [Array<String>] Supported file extensions to sideload.
90
+ # @param options [Hash] Options to pass to `import`.
91
+ # @return [Array<String>] The imported file paths.
92
+ # @raise [ArgumentError] if `filepath` is not an absolute file system path.
93
+ private def _sideload(filepath, extensions, **options) # rubocop:disable Style/AccessModifierDeclarations
84
94
  return unless Proscenium.config.side_load
85
95
 
86
- filepath = Rails.root.join(filepath) unless filepath.is_a?(Pathname)
96
+ if !filepath.is_a?(Pathname) || !filepath.absolute?
97
+ raise ArgumentError, "`filepath` (#{filepath}) must be a `Pathname`, and an absolute path"
98
+ end
99
+
100
+ # Ensures extensions with more than one dot are handled correctly.
87
101
  filepath = filepath.sub_ext('')
88
102
 
89
- CSS_EXTENSIONS.find do |x|
103
+ sideloaded = []
104
+
105
+ extensions.find do |x|
90
106
  if (fp = filepath.sub_ext(x)).exist?
91
- import(Resolver.resolve(fp.to_s), sideloaded: true, **options)
107
+ sideloaded << import(Resolver.resolve(fp.to_s), sideloaded: filepath, **options)
92
108
  end
93
109
  end
110
+
111
+ sideloaded
94
112
  end
95
113
 
96
114
  def each_stylesheet(delete: false)
@@ -5,33 +5,34 @@ require 'active_support/log_subscriber'
5
5
  module Proscenium
6
6
  class LogSubscriber < ActiveSupport::LogSubscriber
7
7
  def sideload(event)
8
+ path = event.payload[:identifier]
9
+ sideloaded = event.payload[:sideloaded]
10
+ sideloaded = sideloaded.relative_path_from(Rails.root) if sideloaded.is_a?(Pathname)
11
+
8
12
  info do
9
- " [Proscenium] Side loaded #{event.payload[:identifier]}"
13
+ msg = " #{color('[Proscenium]', nil, bold: true)} Sideloading #{path}"
14
+ sideloaded.is_a?(Pathname) ? msg << " from #{sideloaded}" : msg
10
15
  end
11
16
  end
12
17
 
13
- def build_to_path(event)
18
+ def build(event)
14
19
  path = event.payload[:identifier]
15
- cached = event.payload[:cached] ? ' | Cached!' : ''
16
20
  path = CGI.unescape(path) if path.start_with?(/https?%3A%2F%2F/)
17
21
 
18
22
  info do
19
- message = " #{color('[Proscenium]', nil, bold: true)} Building (to path) #{path}"
20
- message << " (Duration: #{event.duration.round(1)}ms | " \
21
- "Allocations: #{event.allocations}#{cached})"
23
+ message = "#{color('[Proscenium]', nil, bold: true)} Building /#{path}"
24
+ message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
22
25
  end
23
26
  end
24
27
 
25
- def build_to_string(event)
28
+ def resolve(event)
26
29
  path = event.payload[:identifier]
27
30
  path = CGI.unescape(path) if path.start_with?(/https?%3A%2F%2F/)
28
31
 
29
32
  info do
30
- message = " #{color('[Proscenium]', nil, bold: true)} Building #{path}"
33
+ message = " #{color('[Proscenium]', nil, bold: true)} Resolving #{path}"
31
34
  message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
32
35
  end
33
36
  end
34
37
  end
35
38
  end
36
-
37
- Proscenium::LogSubscriber.attach_to :proscenium
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'oj'
4
-
5
3
  module Proscenium
6
4
  class Middleware
7
5
  class Base
@@ -79,18 +77,25 @@ module Proscenium
79
77
  end
80
78
  end
81
79
 
82
- def render_response(content)
80
+ def render_response(result)
81
+ content = result[:response]
82
+
83
83
  response = Rack::Response.new
84
- response.write content
85
- response.content_type = content_type
86
84
  response['X-Proscenium-Middleware'] = name
87
85
  response.set_header 'SourceMap', "#{@request.path_info}.map"
86
+ response.content_type = content_type
87
+ response.etag = result[:content_hash]
88
88
 
89
89
  if Proscenium.config.cache_query_string && Proscenium.config.cache_max_age
90
90
  response.cache! Proscenium.config.cache_max_age
91
91
  end
92
92
 
93
- yield response if block_given?
93
+ if @request.fresh?(response)
94
+ response.status = 304
95
+ response.body = []
96
+ else
97
+ response.write content
98
+ end
94
99
 
95
100
  response.finish
96
101
  end
@@ -6,22 +6,21 @@ module Proscenium
6
6
  class CompileError < Base::CompileError
7
7
  def initialize(args)
8
8
  detail = args[:detail]
9
- detail = ActiveSupport::HashWithIndifferentAccess.new(Oj.load(detail, mode: :strict))
9
+ detail = JSON.parse(detail, mode: :strict)
10
10
 
11
- args[:detail] = if detail[:location]
12
- "#{detail[:text]} in #{detail[:location][:file]}:" +
13
- detail[:location][:line].to_s
14
- else
15
- detail[:text]
16
- end
11
+ args['detail'] = if detail['location']
12
+ "#{detail['text']} in #{detail['location']['file']}:" +
13
+ detail['location']['line'].to_s
14
+ else
15
+ detail['text']
16
+ end
17
17
 
18
18
  super
19
19
  end
20
20
  end
21
21
 
22
22
  def attempt
23
- render_response Builder.build_to_string(path_to_build, root: Rails.root.to_s,
24
- base_url: @request.base_url)
23
+ render_response Builder.build_to_string(path_to_build)
25
24
  rescue Builder::CompileError => e
26
25
  raise self.class::CompileError, { file: @request.fullpath, detail: e.message }, caller
27
26
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Proscenium
4
+ class Middleware
5
+ class RubyGems < Esbuild
6
+ def real_path
7
+ @real_path ||= Pathname.new(gem_request_path.delete_prefix("#{gem_name}/")).to_s
8
+ end
9
+
10
+ def root_for_readable
11
+ BundledGems.pathname_for!(gem_name)
12
+ end
13
+
14
+ def gem_name
15
+ @gem_name ||= gem_request_path.split('/').first
16
+ end
17
+
18
+ def gem_request_path
19
+ @gem_request_path ||= @request.path.delete_prefix('/node_modules/@rubygems/')
20
+ end
21
+ end
22
+ end
23
+ end
@@ -9,8 +9,7 @@ module Proscenium
9
9
 
10
10
  autoload :Base
11
11
  autoload :Esbuild
12
- autoload :Engines
13
- autoload :Runtime
12
+ autoload :RubyGems
14
13
 
15
14
  def initialize(app)
16
15
  @app = app
@@ -21,10 +20,25 @@ module Proscenium
21
20
  end
22
21
 
23
22
  def call(env)
24
- request = Rack::Request.new(env)
23
+ request = ActionDispatch::Request.new(env)
25
24
 
26
25
  return @app.call(env) if !request.get? && !request.head?
27
- return @chunk_handler.attempt(request.env) if request.path.match?(%r{^/_asset_chunks/})
26
+
27
+ if request.path.match?(%r{^/_asset_chunks/})
28
+ response = Rack::Response[*@chunk_handler.attempt(request.env)]
29
+ response.etag = request.path.match(/-\$([a-z0-9]+)\$/i)[1]
30
+
31
+ if Proscenium.config.cache_query_string && Proscenium.config.cache_max_age
32
+ response.cache! Proscenium.config.cache_max_age
33
+ end
34
+
35
+ if request.fresh?(response)
36
+ response.status = 304
37
+ response.body = []
38
+ end
39
+
40
+ return response.finish
41
+ end
28
42
 
29
43
  attempt(request) || @app.call(env)
30
44
  end
@@ -34,41 +48,29 @@ module Proscenium
34
48
  def attempt(request)
35
49
  return unless (type = find_type(request))
36
50
 
37
- # file_handler.attempt(request.env) || type.attempt(request)
38
-
39
51
  type.attempt request
40
52
  end
41
53
 
42
54
  def find_type(request)
43
- return Runtime if request.path.match?(%r{^/@proscenium/})
44
- return Esbuild if Pathname.new(request.path).fnmatch?(app_path_glob, File::FNM_EXTGLOB)
45
-
46
55
  pathname = Pathname.new(request.path)
47
- Engines if pathname.fnmatch?(ui_path_glob, File::FNM_EXTGLOB) ||
48
- pathname.fnmatch?(engines_path_glob, File::FNM_EXTGLOB)
56
+
57
+ if pathname.fnmatch?(gems_path_glob, File::FNM_EXTGLOB)
58
+ RubyGems
59
+ elsif pathname.fnmatch?(app_path_glob, File::FNM_EXTGLOB)
60
+ Esbuild
61
+ end
49
62
  end
50
63
 
51
64
  def app_path_glob
52
65
  "/{#{Proscenium::ALLOWED_DIRECTORIES}}/**.{#{file_extensions}}"
53
66
  end
54
67
 
55
- def engines_path_glob
56
- names = Proscenium.config.engines.map(&:engine_name)
57
- "/{#{names.join(',')}}/{#{Proscenium::ALLOWED_DIRECTORIES}}/**.{#{file_extensions}}"
58
- end
59
-
60
- def ui_path_glob
61
- "/proscenium/ui/**.{#{file_extensions}}"
68
+ def gems_path_glob
69
+ "/node_modules/@rubygems/**.{#{file_extensions}}"
62
70
  end
63
71
 
64
72
  def file_extensions
65
73
  @file_extensions ||= FILE_EXTENSIONS.join(',')
66
74
  end
67
-
68
- # TODO: handle precompiled assets
69
- # def file_handler
70
- # ::ActionDispatch::FileHandler.new Rails.public_path.join('assets').to_s,
71
- # headers: { 'X-Proscenium-Middleware' => 'precompiled' }
72
- # end
73
75
  end
74
76
  end
@@ -1,24 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Proscenium
4
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
5
4
  module Monkey
6
5
  module TemplateRenderer
7
6
  private
8
7
 
9
- def render_template(view, template, layout_name, locals) # rubocop:disable Metrics/*
8
+ def render_template(view, template, layout_name, locals)
10
9
  result = super
11
10
  return result if !view.controller || !Proscenium.config.side_load
12
11
 
13
- renderable = template.instance_variable_get(:@renderable)
14
-
15
- to_sideload = if Object.const_defined?(:ViewComponent) &&
16
- template.is_a?(ActionView::Template::Renderable) &&
17
- renderable.class < ::ViewComponent::Base &&
18
- renderable.class.format == :html
19
- renderable
20
- elsif template.respond_to?(:virtual_path) &&
21
- template.respond_to?(:type) && template.type == :html
12
+ to_sideload = if template.respond_to?(:virtual_path) &&
13
+ template.respond_to?(:type) && template.type == :html
22
14
  template
23
15
  end
24
16
  if to_sideload
@@ -48,7 +40,7 @@ module Proscenium
48
40
  options[k] = controller.instance_eval(&options[k]) if options[k].is_a?(Proc)
49
41
  end
50
42
 
51
- Importer.sideload "app/views/#{tpl.virtual_path}", **options
43
+ Importer.sideload Rails.root.join("app/views/#{tpl.virtual_path}"), **options
52
44
  end
53
45
  end
54
46
 
@@ -87,9 +79,8 @@ module Proscenium
87
79
  options[k] = controller.instance_eval(&options[k]) if options[k].is_a?(Proc)
88
80
  end
89
81
 
90
- Importer.sideload "app/views/#{tpl.virtual_path}", **options
82
+ Importer.sideload Rails.root.join("app/views/#{tpl.virtual_path}"), **options
91
83
  end
92
84
  end
93
85
  end
94
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
95
86
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rails'
4
- require 'proscenium/log_subscriber'
5
4
 
6
5
  ENV['RAILS_ENV'] = Rails.env
7
6
 
@@ -11,14 +10,11 @@ module Proscenium
11
10
 
12
11
  config.proscenium = ActiveSupport::OrderedOptions.new
13
12
  config.proscenium.debug = false
13
+ config.proscenium.logging = true
14
+ config.proscenium.bundle = true
14
15
  config.proscenium.side_load = true
15
16
  config.proscenium.code_splitting = true
16
-
17
- # Cache asset paths when building to path. Enabled by default in production.
18
- # @see Proscenium::Builder#build_to_path
19
- config.proscenium.cache = ActiveSupport::Cache::MemoryStore.new if Rails.env.production?
20
-
21
- # TODO: implement!
17
+ config.proscenium.ensure_loaded = :raise
22
18
  config.proscenium.cache_query_string = Rails.env.production? && ENV.fetch('REVISION', nil)
23
19
  config.proscenium.cache_max_age = 2_592_000 # 30 days
24
20
 
@@ -27,45 +23,28 @@ module Proscenium
27
23
  # defined means a faster build, as esbuild will have less to do.
28
24
  config.proscenium.env_vars = Set.new
29
25
 
30
- # Rails engines to expose and allow Proscenium to serve their assets.
31
- #
32
- # A Rails engine that has assets, can add Proscenium as a gem dependency, and then add itself
33
- # to this list. Proscenium will then serve the engine's assets at the URL path beginning with
34
- # the engine name.
35
- #
36
- # Example:
37
- # class Gem1::Engine < ::Rails::Engine
38
- # config.proscenium.engines << self
39
- # end
40
- config.proscenium.engines = Set.new
41
-
42
26
  config.action_dispatch.rescue_templates = {
43
27
  'Proscenium::Builder::BuildError' => 'build_error'
44
28
  }
45
29
 
46
30
  config.after_initialize do |_app|
47
- ActiveSupport.on_load(:action_view) do
48
- include Proscenium::Helper
31
+ if config.proscenium.logging
32
+ require 'proscenium/log_subscriber'
33
+ Proscenium::LogSubscriber.attach_to :proscenium
49
34
  end
50
- end
51
35
 
52
- initializer 'proscenium.ui' do
53
- ActiveSupport::Inflector.inflections(:en) do |inflect|
54
- inflect.acronym 'UI'
36
+ ActiveSupport.on_load(:action_view) do
37
+ include Proscenium::Helper
55
38
  end
56
39
  end
57
40
 
58
41
  initializer 'proscenium.debugging' do
59
- if Rails.gem_version >= Gem::Version.new('7.1.0')
60
- tpl_path = root.join('lib', 'proscenium', 'templates').to_s
61
- ActionDispatch::DebugView::RESCUES_TEMPLATE_PATHS << tpl_path
62
- end
42
+ tpl_path = root.join('lib', 'proscenium', 'templates').to_s
43
+ ActionDispatch::DebugView::RESCUES_TEMPLATE_PATHS << tpl_path
63
44
  end
64
45
 
65
46
  initializer 'proscenium.middleware' do |app|
66
- app.middleware.insert_after ActionDispatch::Static, Middleware
67
- app.middleware.insert_after ActionDispatch::Static, Rack::ETag, 'no-cache'
68
- app.middleware.insert_after ActionDispatch::Static, Rack::ConditionalGet
47
+ app.middleware.insert_after ActionDispatch::Static, Proscenium::Middleware
69
48
  end
70
49
 
71
50
  initializer 'proscenium.sideloading' do
@@ -81,26 +60,5 @@ module Proscenium
81
60
  ActionView::PartialRenderer.prepend Monkey::PartialRenderer
82
61
  end
83
62
  end
84
-
85
- initializer 'proscenium.public_path' do |app|
86
- if app.config.public_file_server.enabled
87
- headers = app.config.public_file_server.headers || {}
88
- index = app.config.public_file_server.index_name || 'index'
89
-
90
- app.middleware.insert_after(ActionDispatch::Static, ActionDispatch::Static,
91
- root.join('public').to_s, index:, headers:)
92
- end
93
- end
94
- end
95
- end
96
-
97
- if Rails.gem_version < Gem::Version.new('7.1.0')
98
- class ActionDispatch::DebugView
99
- def initialize(assigns)
100
- tpl_path = Proscenium::Railtie.root.join('lib', 'proscenium', 'templates').to_s
101
- paths = [RESCUES_TEMPLATE_PATH, tpl_path]
102
- lookup_context = ActionView::LookupContext.new(paths)
103
- super(lookup_context, assigns, nil)
104
- end
105
63
  end
106
64
  end
@@ -1,15 +1,5 @@
1
- window.Proscenium = window.Proscenium || { lazyScripts: {} };
2
1
  const pathAttribute = "data-proscenium-component-path";
3
2
 
4
- // Find lazyscripts JSON already in the DOM.
5
- const element = document.querySelector("#prosceniumLazyScripts");
6
- if (element) {
7
- window.Proscenium.lazyScripts = {
8
- ...window.Proscenium.lazyScripts,
9
- ...JSON.parse(element.text),
10
- };
11
- }
12
-
13
3
  // Find components already in the DOM.
14
4
  const elements = document.querySelectorAll(`[${pathAttribute}]`);
15
5
  elements.length > 0 && init(elements);
@@ -17,12 +7,7 @@ elements.length > 0 && init(elements);
17
7
  new MutationObserver((mutationsList) => {
18
8
  for (const { addedNodes } of mutationsList) {
19
9
  for (const ele of addedNodes) {
20
- if (ele.tagName === "SCRIPT" && ele.id === "prosceniumLazyScripts") {
21
- window.Proscenium.lazyScripts = {
22
- ...window.Proscenium.lazyScripts,
23
- ...JSON.parse(ele.text),
24
- };
25
- } else if (ele.matches(`[${pathAttribute}]`)) {
10
+ if (ele.matches(`[${pathAttribute}]`)) {
26
11
  init([ele]);
27
12
  }
28
13
  }
@@ -81,12 +66,8 @@ function init(elements) {
81
66
  // For testing and simulation of slow connections.
82
67
  // const sim = new Promise((resolve) => setTimeout(resolve, 5000));
83
68
 
84
- if (!window.Proscenium.lazyScripts[path]) {
85
- throw `[proscenium/react/manager] Cannot load component ${path} (not found in Proscenium.lazyScripts)`;
86
- }
87
-
88
- const react = import("@proscenium/react-manager/react");
89
- const Component = import(window.Proscenium.lazyScripts[path].outpath);
69
+ const react = import("@rubygems/proscenium/react-manager/react");
70
+ const Component = import(path);
90
71
 
91
72
  const forwardChildren =
92
73
  "prosceniumComponentForwardChildren" in element.dataset &&
@@ -11,7 +11,7 @@ module Proscenium
11
11
  # The HTML tag to use as the wrapping element for the component. You can reassign this in your
12
12
  # component class to use a different tag:
13
13
  #
14
- # class MyComponent < Proscenium::ViewComponent::ReactComponent
14
+ # class MyComponent < Proscenium::ReactComponent
15
15
  # self.root_tag = :span
16
16
  # end
17
17
  #
@@ -40,13 +40,12 @@ module Proscenium
40
40
  class_attribute :loader
41
41
 
42
42
  # @return [String] the URL path to the component manager.
43
- class_attribute :manager, default: '/@proscenium/react-manager/index.jsx'
43
+ class_attribute :manager, default: '/proscenium/react-manager/index.jsx'
44
44
  end
45
45
 
46
46
  class_methods do
47
47
  def sideload(options)
48
48
  Importer.import manager, **options, js: { type: 'module' }
49
- Importer.sideload source_path, lazy: true, **options
50
49
  end
51
50
  end
52
51