proscenium 0.9.1-aarch64-linux → 0.11.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 (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
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proscenium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.11.0
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Joel Moss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-11 00:00:00.000000000 Z
11
+ date: 2023-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -36,28 +36,14 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 1.15.5
39
+ version: 1.16.3
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: 1.15.5
47
- - !ruby/object:Gem::Dependency
48
- name: nokogiri
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '1.13'
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '1.13'
46
+ version: 1.16.3
61
47
  - !ruby/object:Gem::Dependency
62
48
  name: oj
63
49
  requirement: !ruby/object:Gem::Requirement
@@ -72,34 +58,6 @@ dependencies:
72
58
  - - "~>"
73
59
  - !ruby/object:Gem::Version
74
60
  version: '3.13'
75
- - !ruby/object:Gem::Dependency
76
- name: phlex
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: 1.8.1
82
- type: :runtime
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: 1.8.1
89
- - !ruby/object:Gem::Dependency
90
- name: phlex-rails
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: 1.0.0
96
- type: :runtime
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: 1.0.0
103
61
  - !ruby/object:Gem::Dependency
104
62
  name: railties
105
63
  requirement: !ruby/object:Gem::Requirement
@@ -131,34 +89,42 @@ files:
131
89
  - LICENSE.txt
132
90
  - README.md
133
91
  - lib/proscenium.rb
92
+ - lib/proscenium/builder.rb
134
93
  - lib/proscenium/css_module.rb
135
- - lib/proscenium/css_module/class_names_resolver.rb
136
- - lib/proscenium/css_module/resolver.rb
137
- - lib/proscenium/current.rb
138
- - lib/proscenium/esbuild.rb
139
- - lib/proscenium/esbuild/golib.rb
94
+ - lib/proscenium/css_module/path.rb
95
+ - lib/proscenium/css_module/transformer.rb
96
+ - lib/proscenium/ensure_loaded.rb
140
97
  - lib/proscenium/ext/proscenium
141
98
  - lib/proscenium/ext/proscenium.h
142
99
  - lib/proscenium/helper.rb
100
+ - lib/proscenium/importer.rb
101
+ - lib/proscenium/libs/react-manager/index.jsx
102
+ - lib/proscenium/libs/react-manager/react.js
103
+ - lib/proscenium/libs/stimulus-loading.js
104
+ - lib/proscenium/libs/test.js
143
105
  - lib/proscenium/log_subscriber.rb
144
106
  - lib/proscenium/middleware.rb
145
107
  - lib/proscenium/middleware/base.rb
108
+ - lib/proscenium/middleware/engines.rb
146
109
  - lib/proscenium/middleware/esbuild.rb
110
+ - lib/proscenium/middleware/runtime.rb
147
111
  - lib/proscenium/middleware/url.rb
112
+ - lib/proscenium/monkey.rb
148
113
  - lib/proscenium/phlex.rb
149
- - lib/proscenium/phlex/component_concerns.rb
150
- - lib/proscenium/phlex/page.rb
114
+ - lib/proscenium/phlex/css_modules.rb
151
115
  - lib/proscenium/phlex/react_component.rb
152
- - lib/proscenium/phlex/resolve_css_modules.rb
153
116
  - lib/proscenium/railtie.rb
117
+ - lib/proscenium/react_componentable.rb
118
+ - lib/proscenium/resolver.rb
154
119
  - lib/proscenium/side_load.rb
155
- - lib/proscenium/side_load/ensure_loaded.rb
156
- - lib/proscenium/side_load/helper.rb
157
- - lib/proscenium/side_load/monkey.rb
120
+ - lib/proscenium/source_path.rb
121
+ - lib/proscenium/templates/rescues/build_error.html.erb
122
+ - lib/proscenium/utils.rb
158
123
  - lib/proscenium/version.rb
159
124
  - lib/proscenium/view_component.rb
125
+ - lib/proscenium/view_component/css_modules.rb
160
126
  - lib/proscenium/view_component/react_component.rb
161
- - lib/proscenium/view_component/tag_builder.rb
127
+ - lib/proscenium/view_component/sideload.rb
162
128
  homepage: https://github.com/joelmoss/proscenium
163
129
  licenses:
164
130
  - MIT
@@ -182,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
148
  - !ruby/object:Gem::Version
183
149
  version: '0'
184
150
  requirements: []
185
- rubygems_version: 3.4.13
151
+ rubygems_version: 3.4.20
186
152
  signing_key:
187
153
  specification_version: 4
188
154
  summary: The engine powering your Rails frontend
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Proscenium
4
- class CssModule::ClassNamesResolver
5
- def initialize(class_names, phlex_path)
6
- @class_names = class_names.split
7
- @stylesheets = {}
8
- @phlex_path = phlex_path.sub_ext('.module.css')
9
-
10
- resolve_class_names
11
- end
12
-
13
- def class_names
14
- @class_names.join(' ')
15
- end
16
-
17
- def stylesheets
18
- @stylesheets.map { |_, values| values[:resolved_path] }
19
- end
20
-
21
- private
22
-
23
- def resolve_class_names
24
- @class_names.map! do |class_name|
25
- if class_name.include?('/')
26
- if class_name.starts_with?('@')
27
- # Scoped bare specifier (eg. "@scoped/package/lib/button@default").
28
- _, path, name = class_name.split('@')
29
- path = "@#{path}"
30
- elsif class_name.starts_with?('/')
31
- # Local path with leading slash.
32
- path, name = class_name[1..].split('@')
33
- else
34
- # Bare specifier (eg. "mypackage/lib/button@default").
35
- path, name = class_name.split('@')
36
- end
37
-
38
- path += '.module.css'
39
-
40
- Utils.css_modularise_class_name name, digest: add_stylesheet(path)[:digest]
41
- elsif class_name.starts_with?('@')
42
- Utils.css_modularise_class_name class_name[1..],
43
- digest: add_stylesheet(@phlex_path)[:digest]
44
- else
45
- class_name
46
- end
47
- end
48
- end
49
-
50
- def add_stylesheet(path)
51
- return @stylesheets[path] if @stylesheets.key?(path)
52
-
53
- resolved_path = Utils.resolve_path(path.to_s)
54
-
55
- unless Rails.root.join(resolved_path[1..]).exist?
56
- raise CssModule::StylesheetNotFound, resolved_path
57
- end
58
-
59
- # Note that the digest is based on the resolved (URL) path, not the original path.
60
- @stylesheets[path] = {
61
- resolved_path: resolved_path,
62
- digest: Utils.digest(resolved_path)
63
- }
64
- end
65
- end
66
- end
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Proscenium
4
- class CssModule::Resolver
5
- attr_reader :side_loaded_paths
6
-
7
- # @param path [Pathname] Absolute file system path to the Ruby file that will be side loaded.
8
- def initialize(path, side_load: true, hash: nil)
9
- raise ArgumentError, "'#{path}' must be a `Pathname`" unless path.is_a?(Pathname)
10
-
11
- @path = path
12
- @hash = hash
13
- @css_module_path = path.sub_ext('.module.css')
14
- @side_load = side_load
15
- @side_loaded_paths = nil
16
- end
17
-
18
- # Parses the given `content` for CSS modules names ('class' attributes beginning with '@'), and
19
- # returns the content with said CSS Modules replaced with the compiled class names.
20
- #
21
- # Example:
22
- # <div class="@my_css_module_name"></div>
23
- def compile_class_names(content)
24
- doc = Nokogiri::HTML::DocumentFragment.parse(content)
25
-
26
- return content if (modules = doc.css('[class*="@"]')).empty?
27
-
28
- modules.each do |ele|
29
- classes = ele.classes.map { |cls| cls.starts_with?('@') ? class_names!(cls[1..]) : cls }
30
- ele['class'] = classes.join(' ')
31
- end
32
-
33
- doc.to_html.html_safe
34
- end
35
-
36
- # Resolves the given CSS class names to CSS modules. This will also side load the stylesheet if
37
- # it exists.
38
- #
39
- # @param names [String, Array]
40
- # @returns [Array] of class names generated from the given CSS module `names`.
41
- def class_names(*names)
42
- side_load_css_module
43
- Utils.css_modularise_class_names names, digest: @hash
44
- end
45
-
46
- # Like #class_names, but requires that the stylesheet exists.
47
- #
48
- # @param names [String, Array]
49
- # @raises Proscenium::CssModule::NotFound if stylesheet does not exists.
50
- # @see #class_names
51
- def class_names!(...)
52
- raise CssModule::StylesheetNotFound, @css_module_path unless @css_module_path.exist?
53
-
54
- class_names(...)
55
- end
56
-
57
- def side_loaded?
58
- @side_loaded_paths.present?
59
- end
60
-
61
- private
62
-
63
- def side_load_css_module
64
- return if !@side_load || !Rails.application.config.proscenium.side_load
65
-
66
- paths = SideLoad.append @path, { '.module.css' => :css }
67
-
68
- @side_loaded_paths = if paths.empty?
69
- nil
70
- else
71
- @hash = Utils.digest(paths[0])
72
- paths
73
- end
74
- end
75
- end
76
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/current_attributes'
4
-
5
- module Proscenium
6
- class Current < ActiveSupport::CurrentAttributes
7
- attribute :loaded
8
- end
9
- end
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ffi'
4
- require 'oj'
5
-
6
- module Proscenium
7
- class Esbuild::Golib
8
- class Result < FFI::Struct
9
- layout :success, :bool,
10
- :response, :string
11
- end
12
-
13
- module Request
14
- extend FFI::Library
15
- ffi_lib Pathname.new(__dir__).join('../ext/proscenium').to_s
16
-
17
- enum :environment, [:development, 1, :test, :production]
18
-
19
- attach_function :build, [
20
- :string, # path or entry point
21
- :string, # root
22
- :string, # base URL of the Rails app. eg. https://example.com
23
- :environment, # Rails environment as a Symbol
24
- :string, # path to import map, relative to root
25
- :bool # debugging enabled?
26
- ], Result.by_value
27
-
28
- attach_function :resolve, [
29
- :string, # path or entry point
30
- :string, # root
31
- :environment, # Rails environment as a Symbol
32
- :string # path to import map, relative to root
33
- ], Result.by_value
34
- end
35
-
36
- class BuildError < StandardError
37
- attr_reader :error, :path
38
-
39
- def initialize(path, error)
40
- error = Oj.load(error, mode: :strict).deep_transform_keys(&:underscore)
41
-
42
- super "Failed to build '#{path}' -- #{error['text']}"
43
- end
44
- end
45
-
46
- class ResolveError < StandardError
47
- attr_reader :error_msg, :path
48
-
49
- def initialize(path, error_msg)
50
- super "Failed to resolve '#{path}' -- #{error_msg}"
51
- end
52
- end
53
-
54
- def initialize(root: nil, base_url: nil)
55
- @root = root || Rails.root
56
- @base_url = base_url
57
- end
58
-
59
- def self.resolve(path)
60
- new.resolve(path)
61
- end
62
-
63
- def self.build(path)
64
- new.build(path)
65
- end
66
-
67
- def build(path)
68
- result = Request.build(path, @root.to_s, @base_url, Rails.env.to_sym, import_map,
69
- Rails.env.development?)
70
- raise BuildError.new(path, result[:response]) unless result[:success]
71
-
72
- result[:response]
73
- end
74
-
75
- def resolve(path)
76
- result = Request.resolve(path, @root.to_s, Rails.env.to_sym, import_map)
77
- raise ResolveError.new(path, result[:response]) unless result[:success]
78
-
79
- result[:response]
80
- end
81
-
82
- private
83
-
84
- def import_map
85
- return unless (path = Rails.root&.join('config'))
86
-
87
- if (json = path.join('import_map.json')).exist?
88
- return json.relative_path_from(@root).to_s
89
- end
90
- if (js = path.join('import_map.js')).exist?
91
- return js.relative_path_from(@root).to_s
92
- end
93
-
94
- nil
95
- end
96
- end
97
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Proscenium
4
- class Esbuild
5
- class CompileError < StandardError; end
6
-
7
- extend ActiveSupport::Autoload
8
-
9
- autoload :Golib
10
-
11
- def self.build(...)
12
- new(...).build
13
- end
14
-
15
- def initialize(path, root:, base_url:)
16
- @path = path
17
- @root = root
18
- @base_url = base_url
19
- end
20
-
21
- def build
22
- Proscenium::Esbuild::Golib.new(root: @root, base_url: @base_url).build(@path)
23
- end
24
-
25
- private
26
-
27
- def cache_query_string
28
- q = Proscenium.config.cache_query_string
29
- q ? "--cache-query-string #{q}" : nil
30
- end
31
- end
32
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Proscenium::Phlex::ComponentConcerns
4
- module CssModules
5
- extend ActiveSupport::Concern
6
- include Proscenium::CssModule
7
- include Proscenium::Phlex::ResolveCssModules
8
-
9
- # class_methods do
10
- # # FIXME: Still needed?
11
- # def path
12
- # pp name, super
13
- # pp Module.const_source_location(name).first
14
-
15
- # name && Pathname.new(Module.const_source_location(name).first)
16
- # rescue NameError
17
- # nil
18
- # end
19
- # end
20
-
21
- private
22
-
23
- def path
24
- self.class.path
25
- end
26
- end
27
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'phlex/rails'
4
-
5
- # Include this in your view for additional logic for rendering a full HTML page, usually from a
6
- # controller.
7
- module Proscenium::Phlex::Page
8
- include Phlex::Rails::Helpers::CSPMetaTag
9
- include Phlex::Rails::Helpers::CSRFMetaTags
10
- include Phlex::Rails::Helpers::FaviconLinkTag
11
- include Phlex::Rails::Helpers::PreloadLinkTag
12
- include Phlex::Rails::Helpers::StyleSheetLinkTag
13
- include Phlex::Rails::Helpers::ActionCableMetaTag
14
- include Phlex::Rails::Helpers::AutoDiscoveryLinkTag
15
- include Phlex::Rails::Helpers::JavaScriptIncludeTag
16
- include Phlex::Rails::Helpers::JavaScriptImportMapTags
17
- include Phlex::Rails::Helpers::JavaScriptImportModuleTag
18
-
19
- def self.included(klass)
20
- klass.extend(Phlex::Rails::Layout::Interface)
21
- end
22
-
23
- def template(&block)
24
- doctype
25
- html do
26
- head
27
- body(&block)
28
- end
29
- end
30
-
31
- private
32
-
33
- def after_template
34
- super
35
- @_buffer.gsub!('<!-- [SIDE_LOAD_STYLESHEETS] -->', capture { side_load_stylesheets })
36
- end
37
-
38
- def page_title
39
- Rails.application.class.name.deconstantize
40
- end
41
-
42
- def head
43
- super do
44
- title { page_title }
45
-
46
- yield if block_given?
47
-
48
- csp_meta_tag
49
- csrf_meta_tags
50
-
51
- comment { '[SIDE_LOAD_STYLESHEETS]' }
52
- end
53
- end
54
-
55
- def body
56
- super do
57
- yield if block_given?
58
-
59
- side_load_javascripts defer: true, type: :module
60
- end
61
- end
62
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Proscenium::SideLoad
4
- module EnsureLoaded
5
- def self.included(child)
6
- child.class_eval do
7
- append_after_action do
8
- if Proscenium::Current.loaded
9
- if Proscenium::Current.loaded[:js].present?
10
- raise NotIncludedError, 'There are javascripts to be side loaded, but they have not ' \
11
- 'been included. Did you forget to add the ' \
12
- '`#side_load_javascripts` helper in your views?'
13
- end
14
-
15
- if Proscenium::Current.loaded[:css].present?
16
- raise NotIncludedError, 'There are stylesheets to be side loaded, but they have not ' \
17
- 'been included. Did you forget to add the ' \
18
- '`#side_load_stylesheets` helper in your views?'
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Proscenium
4
- module SideLoad::Helper
5
- def side_load_stylesheets
6
- return unless Proscenium::Current.loaded
7
-
8
- out = []
9
- Proscenium::Current.loaded[:css].delete_if do |path|
10
- out << stylesheet_link_tag(path, extname: false)
11
- end
12
- out.join("\n").html_safe
13
- end
14
-
15
- def side_load_javascripts(**options)
16
- return unless Proscenium::Current.loaded
17
-
18
- out = []
19
- Proscenium::Current.loaded[:js].delete_if do |path|
20
- out << javascript_include_tag(path, extname: false, **options)
21
- end
22
- out.join("\n").html_safe
23
- end
24
- end
25
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Proscenium::ViewComponent::TagBuilder < ActionView::Helpers::TagHelper::TagBuilder
4
- def tag_options(options, escape = true) # rubocop:disable Style/OptionalBooleanParameter
5
- super(css_module_option(options), escape)
6
- end
7
-
8
- private
9
-
10
- def css_module_option(options)
11
- return options if options.blank?
12
-
13
- unless (css_module = options.delete(:css_module) || options.delete('css_module'))
14
- return options
15
- end
16
-
17
- css_module = @view_context.css_module(css_module)
18
-
19
- options.tap do |x|
20
- x[:class] = "#{css_module} #{options.delete(:class) || options.delete('class')}".strip
21
- end
22
- end
23
- end