proscenium 0.22.3 → 0.22.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ccb4b40b7fedd8ea11b6298c67ad1496933952540cfcc1cbef836b6c3ab3d926
4
- data.tar.gz: c4b0a87cfafb3a4971e893479427194c2b7eaae1cd02f3431b03b6c30d27a632
3
+ metadata.gz: 6fda75c598a47171a1252aa60697a1395322cf1848ac597dc966d0834254c842
4
+ data.tar.gz: fe8d96e72704c1cbb026e15ef952f00e14d41d675ff905527b3a73c06728bc84
5
5
  SHA512:
6
- metadata.gz: e484b00544f438bd0db6a0840d857b052646681f9fd676a80f4e0edf8493e2f934d9ec94753d760fc19c0c98a0b9eca88324bd31d362fbe02feea52c91b94608
7
- data.tar.gz: 52a9e755b968ebf6b6bac499c0c66097487f08f199c2a002b604dd48052ec0efa321a703aee386f9fc58b999f1525c3c5c435147234ca9e16be54a30eeb01176
6
+ metadata.gz: 29ceba0dda58ba6593bce53d2fb768e56b6bee04a67856b51fc58cc2bb9c4ace1ef91d876ce7ae2ca61ee7066278f7bcca4c09247395f4f5d89f1605d1a914ab
7
+ data.tar.gz: 71a830db8253363979d772a160acacd7bb7e0ac32d1061f9de99baf0bb44ebf0f5814ce589717a8fccc7033eb98e478e6ae657c440772096a10b8723fa87111d
@@ -12,6 +12,12 @@ module Proscenium
12
12
  :content_hash, :string
13
13
  end
14
14
 
15
+ class ResolveResult < FFI::Struct
16
+ layout :success, :bool,
17
+ :url_path, :string,
18
+ :abs_path, :string
19
+ end
20
+
15
21
  class CompileResult < FFI::Struct
16
22
  layout :success, :bool,
17
23
  :messages, :string
@@ -32,7 +38,7 @@ module Proscenium
32
38
  attach_function :resolve, [
33
39
  :string, # path or entry point
34
40
  :pointer # Config as JSON.
35
- ], Result.by_value
41
+ ], ResolveResult.by_value
36
42
 
37
43
  attach_function :compile, [
38
44
  :pointer # Config as JSON.
@@ -115,9 +121,9 @@ module Proscenium
115
121
  ActiveSupport::Notifications.instrument('resolve.proscenium', identifier: path) do
116
122
  result = Request.resolve(path, @request_config)
117
123
 
118
- raise ResolveError.new(path, result[:response]) unless result[:success]
124
+ raise ResolveError.new(path, result[:url_path]) unless result[:success]
119
125
 
120
- result[:response]
126
+ [result[:url_path], result[:abs_path]]
121
127
  end
122
128
  end
123
129
 
@@ -66,23 +66,14 @@ module Proscenium
66
66
  raise Proscenium::CssModule::TransformError.new(original_name, 'CSS module path not given')
67
67
  end
68
68
 
69
- manifest_path, non_manifest_path = Resolver.resolve(path.to_s, as_array: true)
70
- digest = Importer.import(manifest_path || non_manifest_path, digest: lambda {
71
- Utils.digest non_manifest_path
72
- })
69
+ digest = Importer.import(path.to_s)
73
70
 
74
- transformed_path = ''
75
- if Rails.env.development?
76
- transformed_path = "__#{non_manifest_path[1..].gsub(%r{[@/.+]}, '-')}"
77
- end
78
71
  transformed_name = name.to_s
79
- transformed_name = if transformed_name.start_with?('_')
80
- "_#{transformed_name[1..]}-#{digest}#{transformed_path}"
81
- else
82
- "#{transformed_name}-#{digest}#{transformed_path}"
83
- end
84
-
85
- [transformed_name, non_manifest_path]
72
+ if transformed_name.start_with?('_')
73
+ "_#{transformed_name[1..]}_#{digest}"
74
+ else
75
+ "#{transformed_name}_#{digest}"
76
+ end
86
77
  end
87
78
  end
88
79
  end
@@ -21,7 +21,7 @@ module Proscenium::CssModule
21
21
  path ||= respond_to?(:css_module_path) ? css_module_path : path
22
22
 
23
23
  cssm = Transformer.new(path)
24
- cssm.class_names(*names, require_prefix: false).map { |name, _| name }.join(' ')
24
+ cssm.class_names(*names, require_prefix: false).join(' ')
25
25
  end
26
26
 
27
27
  def class_names(*names, path: nil)
@@ -29,7 +29,7 @@ module Proscenium::CssModule
29
29
  names = names.flatten.compact
30
30
 
31
31
  cssm = Transformer.new(path)
32
- cssm.class_names(*names).map { |name, _| name }.join(' ') unless names.empty?
32
+ cssm.class_names(*names).join(' ') unless names.empty?
33
33
  end
34
34
  end
35
35
 
@@ -44,7 +44,7 @@ module Proscenium::CssModule
44
44
  # @return [String] the transformed CSS module names concatenated as a string.
45
45
  def css_module(*names, path: nil)
46
46
  transformer = path.nil? ? cssm : Transformer.new(path)
47
- transformer.class_names(*names, require_prefix: false).map { |name, _| name }.join(' ')
47
+ transformer.class_names(*names, require_prefix: false).join(' ')
48
48
  end
49
49
 
50
50
  # @param name [String,Symbol,Array<String,Symbol>]
@@ -53,7 +53,7 @@ module Proscenium::CssModule
53
53
  def class_names(*names, path: nil)
54
54
  names = names.flatten.compact
55
55
  transformer = path.nil? ? cssm : Transformer.new(path)
56
- transformer.class_names(*names).map { |name, _| name }.join(' ') unless names.empty?
56
+ transformer.class_names(*names).join(' ') unless names.empty?
57
57
  end
58
58
 
59
59
  private
Binary file
@@ -28,6 +28,11 @@ struct Result {
28
28
  char* response;
29
29
  char* contentHash;
30
30
  };
31
+ struct ResolveResult {
32
+ int success;
33
+ char* urlPath;
34
+ char* absPath;
35
+ };
31
36
  struct CompileResult {
32
37
  int success;
33
38
  char* messages;
@@ -109,7 +114,7 @@ extern struct Result build_to_string(char* filePath, char* configJson);
109
114
  // - path - The path to build relative to `root`.
110
115
  // - config
111
116
  //
112
- extern struct Result resolve(char* filePath, char* configJson);
117
+ extern struct ResolveResult resolve(char* filePath, char* configJson);
113
118
 
114
119
  // Compile assets using the given `config`.
115
120
  //
@@ -27,8 +27,7 @@ module Proscenium
27
27
  # @return [String] the transformed CSS module names concatenated as a string.
28
28
  def css_module(*names, path: nil)
29
29
  path ||= Pathname.new(@lookup_context.find(@virtual_path).identifier).sub_ext('')
30
- CssModule::Transformer.new(path).class_names(*names, require_prefix: false)
31
- .map { |name, _| name }.join(' ')
30
+ CssModule::Transformer.new(path).class_names(*names, require_prefix: false).join(' ')
32
31
  end
33
32
 
34
33
  def include_assets
@@ -27,31 +27,45 @@ module Proscenium
27
27
  def import(filepath = nil, sideloaded: false, **)
28
28
  self.imported ||= {}
29
29
 
30
- filepath = "/node_modules/#{filepath}" if filepath.start_with?('@rubygems/')
31
- css_module = filepath.match?(/\.module(-\$[a-z0-9]+\$)?\.css$/i)
30
+ return if self.imported.key?(filepath)
31
+
32
+ digest = nil
33
+
34
+ if filepath.end_with?('.module.css')
35
+ manifest_path, non_manifest_path, abs_path = Resolver.resolve(filepath, as_array: true)
36
+ digest = Utils.css_module_digest(abs_path)
37
+ filepath = Array(manifest_path || non_manifest_path)[0]
32
38
 
33
- unless self.imported.key?(filepath)
34
39
  if sideloaded
35
40
  ActiveSupport::Notifications.instrument 'sideload.proscenium', identifier: filepath,
36
41
  sideloaded: do
37
42
  self.imported[filepath] = { ** }
38
- self.imported[filepath][:digest] ||= Utils.digest(filepath) if css_module
39
-
40
- if self.imported[filepath][:digest].is_a?(Proc)
41
- self.imported[filepath][:digest] = self.imported[filepath][:digest].call
42
- end
43
+ self.imported[filepath][:digest] = digest
43
44
  end
44
45
  else
45
46
  self.imported[filepath] = { ** }
46
- self.imported[filepath][:digest] ||= Utils.digest(filepath) if css_module
47
+ self.imported[filepath][:digest] = digest
48
+ end
47
49
 
48
- if self.imported[filepath][:digest].is_a?(Proc)
49
- self.imported[filepath][:digest] = self.imported[filepath][:digest].call
50
+ transformed_path = ''
51
+ if Rails.env.development?
52
+ rel_path = Pathname.new(abs_path).relative_path_from(Rails.root).sub_ext('')
53
+ transformed_path = "_#{rel_path.to_s.gsub(%r{[@/.+]}, '-')}"
54
+ end
55
+
56
+ "#{digest}#{transformed_path}"
57
+ else
58
+ Array(Resolver.resolve(filepath)).each do |fp|
59
+ if sideloaded
60
+ ActiveSupport::Notifications.instrument 'sideload.proscenium', identifier: fp,
61
+ sideloaded: do
62
+ self.imported[fp] = { ** }
63
+ end
64
+ else
65
+ self.imported[fp] = { ** }
50
66
  end
51
67
  end
52
68
  end
53
-
54
- css_module ? self.imported[filepath][:digest] : nil
55
69
  end
56
70
 
57
71
  # Sideloads JS and CSS assets for the given Ruby filepath.
@@ -96,7 +110,6 @@ module Proscenium
96
110
  # @param filepath [Pathname] Absolute file system path of the Ruby file to sideload.
97
111
  # @param extensions [Array<String>] Supported file extensions to sideload.
98
112
  # @param options [Hash] Options to pass to `import`.
99
- # @return [Array<String>] The imported file paths.
100
113
  # @raise [ArgumentError] if `filepath` is not an absolute file system path.
101
114
  private def _sideload(filepath, extensions, **options) # rubocop:disable Style/AccessModifierDeclarations
102
115
  return unless Proscenium.config.side_load
@@ -108,24 +121,11 @@ module Proscenium
108
121
  # Ensures extensions with more than one dot are handled correctly.
109
122
  filepath = filepath.sub_ext('').sub_ext('')
110
123
 
111
- sideloaded = []
112
-
113
124
  extensions.find do |x|
114
125
  next unless (fp = filepath.sub_ext(x)).exist?
115
126
 
116
- sideloaded << if extensions.include?('.module.css')
117
- manifest_path, non_manifest_path = Resolver.resolve(fp.to_s,
118
- as_array: true)
119
- import(manifest_path || non_manifest_path,
120
- sideloaded: filepath,
121
- digest: -> { Utils.digest non_manifest_path },
122
- **options)
123
- else
124
- import(Resolver.resolve(fp.to_s), sideloaded: filepath, **options)
125
- end
127
+ import(fp.to_s, sideloaded: filepath, **options)
126
128
  end
127
-
128
- sideloaded
129
129
  end
130
130
 
131
131
  def each_stylesheet(delete: false)
@@ -31,7 +31,10 @@ module Proscenium
31
31
  ep.delete_prefix(Rails.root.to_s)
32
32
  end
33
33
 
34
- manifest[ep] = "/#{outpath}"
34
+ manifest[ep] = [
35
+ "/#{outpath}",
36
+ details['cssBundle']&.delete_prefix(public_path)
37
+ ].compact
35
38
  end
36
39
  end
37
40
 
@@ -45,7 +45,7 @@ module Proscenium
45
45
 
46
46
  class_methods do
47
47
  def sideload(options)
48
- Importer.import Resolver.resolve(manager.to_s), **options, js: { type: 'module' }
48
+ Importer.import manager.to_s, sideloaded: true, **options, js: { type: 'module' }
49
49
  end
50
50
  end
51
51
 
@@ -58,7 +58,7 @@ module Proscenium
58
58
 
59
59
  # The absolute URL path to the javascript component.
60
60
  def virtual_path
61
- @virtual_path ||= Resolver.resolve self.class.source_path.sub_ext('.jsx').to_s
61
+ @virtual_path ||= Resolver.resolve(self.class.source_path.sub_ext('.jsx').to_s)[0]
62
62
  end
63
63
 
64
64
  def props
@@ -9,10 +9,12 @@ module Proscenium
9
9
 
10
10
  # Resolve the given `path` to a fully qualified URL path.
11
11
  #
12
+ # TODO: cache this across requests in production.
13
+ #
12
14
  # @param path [String] URL path, file system path, or bare specifier (ie. NPM package).
13
- # @param as_array [Boolean] whether or not to return both the manifest path and
14
- # non-manifest path as an array. Only returns the resolved path if false (default).
15
- # @return [String] URL path.
15
+ # @param as_array [Boolean] whether or not to return the manifest path, non-manifest path, and
16
+ # absolute file system path as an array. Only returns the resolved path if false (default).
17
+ # @return [String, Array<String>]
16
18
  def self.resolve(path, as_array: false)
17
19
  self.resolved ||= {}
18
20
 
@@ -22,12 +24,12 @@ module Proscenium
22
24
 
23
25
  self.resolved[path] ||= if (gem = BundledGems.paths.find { |_, v| path.start_with? "#{v}/" })
24
26
  vpath = path.sub(/^#{gem.last}/, "@rubygems/#{gem.first}")
25
- [Proscenium::Manifest[vpath], "/node_modules/#{vpath}"]
27
+ [Proscenium::Manifest[vpath], "/node_modules/#{vpath}", path]
26
28
  elsif path.start_with?("#{Rails.root}/")
27
29
  vpath = path.delete_prefix(Rails.root.to_s)
28
- [Proscenium::Manifest[vpath], vpath]
30
+ [Proscenium::Manifest[vpath], vpath, path]
29
31
  else
30
- [Proscenium::Manifest[path], Builder.resolve(path)]
32
+ [Proscenium::Manifest[path], *Builder.resolve(path)]
31
33
  end
32
34
 
33
35
  as_array ? self.resolved[path] : self.resolved[path][0] || self.resolved[path][1]
@@ -4,9 +4,12 @@ module Proscenium
4
4
  module Utils
5
5
  module_function
6
6
 
7
- # @param value [#to_s] The value to create the digest from. This will usually be a `Pathname`.
7
+ # Returns a short digest for the given `value`, intended for CSS module class name suffixes.
8
+ #
9
+ # @param value [#to_s] The value to create the digest from. This will usually be the absolute
10
+ # file system file path.
8
11
  # @return [String] digest of the given value.
9
- def digest(value)
12
+ def css_module_digest(value)
10
13
  Digest::SHA1.hexdigest(value.to_s)[..7]
11
14
  end
12
15
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Proscenium
4
- VERSION = '0.22.3'
4
+ VERSION = '0.22.4'
5
5
  end
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.22.3
4
+ version: 0.22.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Moss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-11-18 00:00:00.000000000 Z
11
+ date: 2025-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi