proscenium 0.9.1-aarch64-linux → 0.11.0-aarch64-linux

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
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