proscenium 0.9.1-arm64-darwin → 0.11.0-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +451 -65
  3. data/lib/proscenium/builder.rb +144 -0
  4. data/lib/proscenium/css_module/path.rb +31 -0
  5. data/lib/proscenium/css_module/transformer.rb +82 -0
  6. data/lib/proscenium/css_module.rb +12 -25
  7. data/lib/proscenium/ensure_loaded.rb +27 -0
  8. data/lib/proscenium/ext/proscenium +0 -0
  9. data/lib/proscenium/ext/proscenium.h +20 -12
  10. data/lib/proscenium/helper.rb +85 -0
  11. data/lib/proscenium/importer.rb +110 -0
  12. data/lib/proscenium/libs/react-manager/index.jsx +101 -0
  13. data/lib/proscenium/libs/react-manager/react.js +2 -0
  14. data/lib/proscenium/libs/stimulus-loading.js +83 -0
  15. data/lib/proscenium/libs/test.js +1 -0
  16. data/lib/proscenium/log_subscriber.rb +1 -2
  17. data/lib/proscenium/middleware/base.rb +8 -8
  18. data/lib/proscenium/middleware/engines.rb +37 -0
  19. data/lib/proscenium/middleware/esbuild.rb +3 -5
  20. data/lib/proscenium/middleware/runtime.rb +18 -0
  21. data/lib/proscenium/middleware.rb +19 -4
  22. data/lib/proscenium/{side_load/monkey.rb → monkey.rb} +24 -12
  23. data/lib/proscenium/phlex/{resolve_css_modules.rb → css_modules.rb} +28 -16
  24. data/lib/proscenium/phlex/react_component.rb +27 -64
  25. data/lib/proscenium/phlex.rb +11 -30
  26. data/lib/proscenium/railtie.rb +49 -41
  27. data/lib/proscenium/react_componentable.rb +95 -0
  28. data/lib/proscenium/resolver.rb +37 -0
  29. data/lib/proscenium/side_load.rb +13 -72
  30. data/lib/proscenium/source_path.rb +15 -0
  31. data/lib/proscenium/templates/rescues/build_error.html.erb +30 -0
  32. data/lib/proscenium/utils.rb +13 -0
  33. data/lib/proscenium/version.rb +1 -1
  34. data/lib/proscenium/view_component/css_modules.rb +11 -0
  35. data/lib/proscenium/view_component/react_component.rb +15 -28
  36. data/lib/proscenium/view_component/sideload.rb +4 -0
  37. data/lib/proscenium/view_component.rb +8 -31
  38. data/lib/proscenium.rb +23 -68
  39. metadata +25 -59
  40. data/lib/proscenium/css_module/class_names_resolver.rb +0 -66
  41. data/lib/proscenium/css_module/resolver.rb +0 -76
  42. data/lib/proscenium/current.rb +0 -9
  43. data/lib/proscenium/esbuild/golib.rb +0 -97
  44. data/lib/proscenium/esbuild.rb +0 -32
  45. data/lib/proscenium/phlex/component_concerns.rb +0 -27
  46. data/lib/proscenium/phlex/page.rb +0 -62
  47. data/lib/proscenium/side_load/ensure_loaded.rb +0 -25
  48. data/lib/proscenium/side_load/helper.rb +0 -25
  49. data/lib/proscenium/view_component/tag_builder.rb +0 -23
@@ -0,0 +1,2 @@
1
+ export { createElement } from "react";
2
+ export { createRoot } from "react-dom/client";
@@ -0,0 +1,83 @@
1
+ const controllerAttribute = "data-controller";
2
+ const controllerFilenameExtension = ".js";
3
+
4
+ export function lazyLoadControllersFrom(
5
+ under,
6
+ application,
7
+ element = document
8
+ ) {
9
+ lazyLoadExistingControllers(under, application, element);
10
+ lazyLoadNewControllers(under, application, element);
11
+ }
12
+
13
+ function lazyLoadExistingControllers(under, application, element) {
14
+ queryControllerNamesWithin(element).forEach((controllerName) =>
15
+ loadController(controllerName, under, application)
16
+ );
17
+ }
18
+
19
+ function lazyLoadNewControllers(under, application, element) {
20
+ new MutationObserver((mutationsList) => {
21
+ for (const { attributeName, target, type } of mutationsList) {
22
+ switch (type) {
23
+ case "attributes": {
24
+ if (
25
+ attributeName == controllerAttribute &&
26
+ target.getAttribute(controllerAttribute)
27
+ ) {
28
+ extractControllerNamesFrom(target).forEach((controllerName) =>
29
+ loadController(controllerName, under, application)
30
+ );
31
+ }
32
+ }
33
+
34
+ case "childList": {
35
+ lazyLoadExistingControllers(under, application, target);
36
+ }
37
+ }
38
+ }
39
+ }).observe(element, {
40
+ attributeFilter: [controllerAttribute],
41
+ subtree: true,
42
+ childList: true,
43
+ });
44
+ }
45
+
46
+ function queryControllerNamesWithin(element) {
47
+ return Array.from(element.querySelectorAll(`[${controllerAttribute}]`))
48
+ .map(extractControllerNamesFrom)
49
+ .flat();
50
+ }
51
+
52
+ function extractControllerNamesFrom(element) {
53
+ return element
54
+ .getAttribute(controllerAttribute)
55
+ .split(/\s+/)
56
+ .filter((content) => content.length);
57
+ }
58
+
59
+ function loadController(name, under, application) {
60
+ if (canRegisterController(name, application)) {
61
+ import(controllerFilename(name, under))
62
+ .then((module) => registerController(name, module, application))
63
+ .catch((error) =>
64
+ console.error(`Failed to autoload controller: ${name}`, error)
65
+ );
66
+ }
67
+ }
68
+
69
+ function controllerFilename(name, under) {
70
+ return `${under}/${name
71
+ .replace(/--/g, "/")
72
+ .replace(/-/g, "_")}_controller${controllerFilenameExtension}`;
73
+ }
74
+
75
+ function registerController(name, module, application) {
76
+ if (canRegisterController(name, application)) {
77
+ application.register(name, module.default);
78
+ }
79
+ }
80
+
81
+ function canRegisterController(name, application) {
82
+ return !application.router.modulesByIdentifier.has(name);
83
+ }
@@ -0,0 +1 @@
1
+ console.log("/@proscenium/test.js");
@@ -12,12 +12,11 @@ module Proscenium
12
12
 
13
13
  def build(event)
14
14
  path = event.payload[:identifier]
15
- path = path.start_with?(/https?%3A%2F%2F/) ? CGI.unescape(path) : path
15
+ path = CGI.unescape(path) if path.start_with?(/https?%3A%2F%2F/)
16
16
 
17
17
  info do
18
18
  message = +"[Proscenium] Building #{path}"
19
19
  message << " (Duration: #{event.duration.round(1)}ms | Allocations: #{event.allocations})"
20
- message << "\n" if defined?(Rails.env) && Rails.env.development?
21
20
  end
22
21
  end
23
22
  end
@@ -34,12 +34,12 @@ module Proscenium
34
34
  private
35
35
 
36
36
  def real_path
37
- @request.path
37
+ @real_path ||= @request.path
38
38
  end
39
39
 
40
40
  # @return [String] the path to the file without the leading slash which will be built.
41
41
  def path_to_build
42
- @request.path[1..]
42
+ @path_to_build ||= @request.path[1..]
43
43
  end
44
44
 
45
45
  def sourcemap?
@@ -51,24 +51,24 @@ module Proscenium
51
51
  end
52
52
 
53
53
  def file_readable?
54
- return unless (path = clean_path(sourcemap? ? real_path[0...-4] : real_path))
54
+ return false unless (path = clean_path(sourcemap? ? real_path[0...-4] : real_path))
55
55
 
56
- file_stat = File.stat(Pathname(root).join(path.delete_prefix('/').b).to_s)
56
+ file_stat = File.stat(root_for_readable.join(path.delete_prefix('/').b).to_s)
57
57
  rescue SystemCallError
58
58
  false
59
59
  else
60
60
  file_stat.file? && file_stat.readable?
61
61
  end
62
62
 
63
+ def root_for_readable
64
+ Rails.root
65
+ end
66
+
63
67
  def clean_path(file)
64
68
  path = Rack::Utils.unescape_path file.chomp('/').delete_prefix('/')
65
69
  Rack::Utils.clean_path_info path if Rack::Utils.valid_path? path
66
70
  end
67
71
 
68
- def root
69
- @root ||= Rails.root.to_s
70
- end
71
-
72
72
  def content_type
73
73
  case ::File.extname(path_to_build)
74
74
  when '.js', '.mjs', '.ts', '.tsx', '.jsx' then 'application/javascript'
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Proscenium
4
+ class Middleware
5
+ # This middleware handles requests for assets in Rails engines. An engine that wants to expose
6
+ # its assets via Proscenium to the application must add itself to the list of engines in the
7
+ # Proscenium config options `Proscenium.config.engines`.
8
+ #
9
+ # For example, we have a gem that exposes a Rails engine.
10
+ #
11
+ # module Gem1
12
+ # class Engine < ::Rails::Engine
13
+ # config.proscenium.engines << self
14
+ # end
15
+ # end
16
+ #
17
+ # When this gem is installed in any Rails application, its assets will be available at the URL
18
+ # `/gem1/...`. For example, if the gem has a file `lib/styles.css`, it can be requested at
19
+ # `/gem1/lib/styles.css`.
20
+ #
21
+ class Engines < Esbuild
22
+ def real_path
23
+ @real_path ||= Pathname.new(@request.path.delete_prefix("/#{engine.engine_name}")).to_s
24
+ end
25
+
26
+ def root_for_readable
27
+ engine.root
28
+ end
29
+
30
+ def engine
31
+ @engine ||= Proscenium.config.engines.find do |engine|
32
+ @request.path.start_with?("/#{engine.engine_name}")
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -20,11 +20,9 @@ module Proscenium
20
20
  end
21
21
 
22
22
  def attempt
23
- ActiveSupport::Notifications.instrument('build.proscenium', identifier: path_to_build) do
24
- render_response Proscenium::Esbuild.build(path_to_build, root: root,
25
- base_url: @request.base_url)
26
- end
27
- rescue Proscenium::Esbuild::CompileError => e
23
+ render_response Builder.build(path_to_build, root: Rails.root.to_s,
24
+ base_url: @request.base_url)
25
+ rescue Builder::CompileError => e
28
26
  raise self.class::CompileError, { file: @request.fullpath, detail: e.message }, caller
29
27
  end
30
28
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Proscenium
4
+ class Middleware
5
+ class Runtime < Esbuild
6
+ private
7
+
8
+ def real_path
9
+ @real_path ||= Pathname.new(@request.path.sub(%r{^/@proscenium},
10
+ '/lib/proscenium/libs')).to_s
11
+ end
12
+
13
+ def root_for_readable
14
+ Proscenium::Railtie.root
15
+ end
16
+ end
17
+ end
18
+ end
@@ -9,16 +9,23 @@ module Proscenium
9
9
 
10
10
  autoload :Base
11
11
  autoload :Esbuild
12
+ autoload :Engines
13
+ autoload :Runtime
12
14
  autoload :Url
13
15
 
14
16
  def initialize(app)
15
17
  @app = app
18
+
19
+ chunks_path = Rails.public_path.join('assets').to_s
20
+ headers = Rails.application.config.public_file_server.headers || {}
21
+ @chunk_handler = ::ActionDispatch::FileHandler.new(chunks_path, headers: headers)
16
22
  end
17
23
 
18
24
  def call(env)
19
25
  request = Rack::Request.new(env)
20
26
 
21
27
  return @app.call(env) if !request.get? && !request.head?
28
+ return @chunk_handler.attempt(request.env) if request.path.match?(%r{^/_asset_chunks/})
22
29
 
23
30
  attempt(request) || @app.call(env)
24
31
  end
@@ -35,12 +42,20 @@ module Proscenium
35
42
 
36
43
  def find_type(request)
37
44
  return Url if request.path.match?(%r{^/https?%3A%2F%2F})
38
- return Esbuild if Pathname.new(request.path).fnmatch?(path_glob, File::FNM_EXTGLOB)
45
+ return Runtime if request.path.match?(%r{^/@proscenium/})
46
+ return Esbuild if Pathname.new(request.path).fnmatch?(app_path_glob, File::FNM_EXTGLOB)
47
+
48
+ Engines if Pathname.new(request.path).fnmatch?(engines_path_glob, File::FNM_EXTGLOB)
39
49
  end
40
50
 
41
- def path_glob
42
- paths = Rails.application.config.proscenium.include_paths.join(',')
43
- "/{#{paths}}/**.{#{FILE_EXTENSIONS.join(',')}}"
51
+ def app_path_glob
52
+ "/{#{Proscenium::ALLOWED_DIRECTORIES}}/**.{#{FILE_EXTENSIONS.join(',')}}"
53
+ end
54
+
55
+ def engines_path_glob
56
+ names = Proscenium.config.engines.map(&:engine_name)
57
+
58
+ "/{#{names.join(',')}}/{#{Proscenium::ALLOWED_DIRECTORIES}}/**.{#{FILE_EXTENSIONS.join(',')}}"
44
59
  end
45
60
 
46
61
  # TODO: handle precompiled assets
@@ -1,12 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Proscenium::SideLoad
3
+ module Proscenium
4
4
  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
5
5
  module Monkey
6
+ module DebugView
7
+ def initialize(assigns)
8
+ paths = [RESCUES_TEMPLATE_PATH, Rails.root.join('lib', 'templates').to_s]
9
+ lookup_context = ActionView::LookupContext.new(paths)
10
+ super(lookup_context, assigns, nil)
11
+ end
12
+ end
13
+
6
14
  module TemplateRenderer
7
15
  private
8
16
 
9
17
  def render_template(view, template, layout_name, locals)
18
+ return super unless Proscenium.config.side_load
19
+
10
20
  layout = find_layout(layout_name, locals.keys, [formats.first])
11
21
  renderable = template.instance_variable_get(:@renderable)
12
22
 
@@ -14,20 +24,18 @@ class Proscenium::SideLoad
14
24
  template.is_a?(ActionView::Template::Renderable) &&
15
25
  renderable.class < ::ViewComponent::Base && renderable.class.format == :html
16
26
  # Side load controller rendered ViewComponent
17
- Proscenium::SideLoad.append "app/views/#{layout.virtual_path}" if layout
18
- Proscenium::SideLoad.append "app/views/#{renderable.virtual_path}"
27
+ Importer.sideload "app/views/#{layout.virtual_path}" if layout
28
+ Importer.sideload "app/views/#{renderable.virtual_path}"
19
29
  elsif template.respond_to?(:virtual_path) &&
20
30
  template.respond_to?(:type) && template.type == :html
21
- # Side load regular view template.
22
- Proscenium::SideLoad.append "app/views/#{layout.virtual_path}" if layout
31
+ Importer.sideload "app/views/#{layout.virtual_path}" if layout
23
32
 
24
33
  # Try side loading the variant template
25
34
  if template.respond_to?(:variant) && template.variant
26
- Proscenium::SideLoad.append "app/views/#{template.virtual_path}+#{template.variant}"
35
+ Importer.sideload "app/views/#{template.virtual_path}+#{template.variant}"
27
36
  end
28
37
 
29
- # The variant template may not exist (above), so we try the regular non-variant path.
30
- Proscenium::SideLoad.append "app/views/#{template.virtual_path}"
38
+ Importer.sideload "app/views/#{template.virtual_path}"
31
39
  end
32
40
 
33
41
  super
@@ -37,10 +45,14 @@ class Proscenium::SideLoad
37
45
  module PartialRenderer
38
46
  private
39
47
 
40
- def build_rendered_template(content, template)
41
- path = Rails.root.join('app', 'views', template.virtual_path)
42
- cssm = Proscenium::CssModule::Resolver.new(path)
43
- super cssm.compile_class_names(content), template
48
+ def render_partial_template(view, locals, template, layout, block)
49
+ if Proscenium.config.side_load && template.respond_to?(:virtual_path) &&
50
+ template.respond_to?(:type) && template.type == :html
51
+ Importer.sideload "app/views/#{layout.virtual_path}" if layout
52
+ Importer.sideload "app/views/#{template.virtual_path}"
53
+ end
54
+
55
+ super
44
56
  end
45
57
  end
46
58
  end
@@ -1,15 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Proscenium
4
- module Phlex::ResolveCssModules
5
- extend ActiveSupport::Concern
4
+ module Phlex::CssModules
5
+ include Proscenium::CssModule
6
6
 
7
- class_methods do
8
- attr_accessor :side_load_cache
7
+ def self.included(base)
8
+ base.extend CssModule::Path
9
+ base.extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ # Set of CSS module paths that have been resolved after being transformed from 'class' HTML
14
+ # attributes. See #process_attributes. This is here because Phlex caches attributes. Which
15
+ # means while the CSS class names will be transformed, any resolved paths will be lost in
16
+ # subsequent requests.
17
+ attr_accessor :resolved_css_module_paths
9
18
  end
10
19
 
11
20
  def before_template
12
- self.class.side_load_cache ||= Set.new
21
+ self.class.resolved_css_module_paths ||= Concurrent::Set.new
22
+ super
23
+ end
24
+
25
+ def after_template
26
+ self.class.resolved_css_module_paths.each do |path|
27
+ Proscenium::Importer.import path
28
+ end
29
+
13
30
  super
14
31
  end
15
32
 
@@ -44,24 +61,19 @@ module Proscenium
44
61
  # end
45
62
  # end
46
63
  #
47
- # The given class name should be underscored, and the resulting CSS module name will be
48
- # `camelCased` with a lower case first character.
49
- #
50
64
  # @raise [Proscenium::CssModule::Resolver::NotFound] If a CSS module file is not found for the
51
65
  # Phlex class file path.
52
66
  def process_attributes(**attributes)
53
67
  if attributes.key?(:class) && (attributes[:class] = tokens(attributes[:class])).include?('@')
54
- resolver = CssModule::ClassNamesResolver.new(attributes[:class], path)
55
- self.class.side_load_cache.merge resolver.stylesheets
56
- attributes[:class] = resolver.class_names
68
+ names = attributes[:class].is_a?(Array) ? attributes[:class] : attributes[:class].split
69
+
70
+ attributes[:class] = cssm.class_names(*names).map do |name, path|
71
+ self.class.resolved_css_module_paths << path if path
72
+ name
73
+ end
57
74
  end
58
75
 
59
76
  attributes
60
77
  end
61
-
62
- def after_template
63
- super
64
- self.class.side_load_cache&.each { |path| SideLoad.append! path, :css }
65
- end
66
78
  end
67
79
  end
@@ -1,69 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- #
4
- # Renders a div for use with @proscenium/component-manager.
5
- #
6
- # You can pass props to the component in the `:props` keyword argument.
7
- #
8
- # By default, the component is lazy loaded when intersecting using IntersectionObserver. Pass in
9
- # :lazy as false to disable this and render the component immediately.
10
- #
11
- # React components are not side loaded at all.
12
- #
13
- class Proscenium::Phlex::ReactComponent < Phlex::HTML
14
- class << self
15
- attr_accessor :path, :abstract_class
16
-
17
- def inherited(child)
18
- position = caller_locations(1, 1).first.label == 'inherited' ? 2 : 1
19
- child.path = Pathname.new caller_locations(position, 1).first.path.sub(/\.rb$/, '')
20
-
21
- super
3
+ module Proscenium
4
+ # Renders a <div> for use with React components, with data attributes specifying the component
5
+ # path and props.
6
+ #
7
+ # If a block is given, it will be yielded within the div, allowing for a custom "loading" UI. If
8
+ # no block is given, then a "loading..." text will be rendered. It is intended that the component
9
+ # is mounted to this div, and the loading UI will then be replaced with the component's rendered
10
+ # output.
11
+ #
12
+ # You can pass props to the component in the `:props` keyword argument.
13
+ class Phlex::ReactComponent < Phlex
14
+ self.abstract_class = true
15
+
16
+ include ReactComponentable
17
+
18
+ # Override this to provide your own loading UI.
19
+ #
20
+ # @example
21
+ # def template(**attributes, &block)
22
+ # super do
23
+ # 'Look at me! I am loading now...'
24
+ # end
25
+ # end
26
+ #
27
+ # @yield the given block to a `div` within the top level component div.
28
+ def template(**attributes, &block)
29
+ send root_tag, **{ data: data_attributes }.deep_merge(attributes), &block
22
30
  end
23
31
  end
24
-
25
- self.abstract_class = true
26
-
27
- include Proscenium::Phlex::ComponentConcerns::CssModules
28
-
29
- attr_writer :props, :lazy
30
-
31
- # @param props: [Hash]
32
- # @param lazy: [Boolean] Lazy load the component using IntersectionObserver. Default: true.
33
- def initialize(props: {}, lazy: true) # rubocop:disable Lint/MissingSuper
34
- @props = props
35
- @lazy = lazy
36
- end
37
-
38
- # @yield the given block to a `div` within the top level component div. If not given,
39
- # `<div>loading...</div>` will be rendered. Use this to display a loading UI while the component
40
- # is loading and rendered.
41
- def template(**attributes, &block)
42
- component_root(:div, **attributes, &block)
43
- end
44
-
45
- private
46
-
47
- def component_root(element, **attributes, &block)
48
- send element, data: { proscenium_component: component_data }, **attributes, &block
49
- end
50
-
51
- def props
52
- @props ||= {}
53
- end
54
-
55
- def lazy
56
- instance_variable_defined?(:@lazy) ? @lazy : (@lazy = false)
57
- end
58
-
59
- def component_data
60
- {
61
- path: virtual_path, lazy: lazy,
62
- props: props.deep_transform_keys { |k| k.to_s.camelize :lower }
63
- }.to_json
64
- end
65
-
66
- def virtual_path
67
- path.to_s.delete_prefix(Rails.root.to_s)
68
- end
69
32
  end
@@ -5,54 +5,35 @@ require 'phlex-rails'
5
5
  module Proscenium
6
6
  class Phlex < ::Phlex::HTML
7
7
  extend ActiveSupport::Autoload
8
- include Proscenium::CssModule
9
8
 
10
- autoload :Page
9
+ autoload :CssModules
11
10
  autoload :ReactComponent
12
- autoload :ResolveCssModules
13
- autoload :ComponentConcerns
14
11
 
15
12
  extend ::Phlex::Rails::HelperMacros
16
13
  include ::Phlex::Rails::Helpers::JavaScriptIncludeTag
17
14
  include ::Phlex::Rails::Helpers::StyleSheetLinkTag
15
+ include Proscenium::SourcePath
16
+ include CssModules
18
17
 
19
- define_output_helper :side_load_stylesheets
20
- define_output_helper :side_load_javascripts
18
+ define_output_helper :side_load_stylesheets # deprecated
19
+ define_output_helper :include_stylesheets
20
+ define_output_helper :side_load_javascripts # deprecated
21
+ define_output_helper :include_javascripts
22
+ define_output_helper :declare_lazy_scripts
21
23
 
22
- # Side loads the class, and its super classes that respond to `.path`. Assign the
23
- # `abstract_class` class variable to any abstract class, and it will not be side loaded.
24
- # Additionally, if the class responds to `side_load`, then that method is called.
25
24
  module Sideload
26
25
  def before_template
27
- klass = self.class
28
-
29
- if !klass.abstract_class && respond_to?(:side_load, true)
30
- side_load
31
- klass = klass.superclass
32
- end
33
-
34
- while !klass.abstract_class && klass.respond_to?(:path) && klass.path
35
- Proscenium::SideLoad.append klass.path
36
- klass = klass.superclass
37
- end
26
+ Proscenium::SideLoad.sideload_inheritance_chain self
38
27
 
39
28
  super
40
29
  end
41
30
  end
42
31
 
43
32
  class << self
44
- attr_accessor :path, :abstract_class
33
+ attr_accessor :abstract_class
45
34
 
46
35
  def inherited(child)
47
- unless child.path
48
- child.path = if caller_locations(1, 1).first.label == 'inherited'
49
- Pathname.new caller_locations(2, 1).first.path
50
- else
51
- Pathname.new caller_locations(1, 1).first.path
52
- end
53
- end
54
-
55
- child.prepend Sideload if Rails.application.config.proscenium.side_load
36
+ child.prepend Sideload
56
37
 
57
38
  super
58
39
  end