proscenium 0.19.0 → 0.21.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: 9f45989b5341c8a6c55afab7523537b4da02255783ab866295130ca3a7a3d0be
4
- data.tar.gz: 2ba1a421a01a6f6ffe0fa7ce3a196109ea8c44bd13887a4be10daa9e40b29cd3
3
+ metadata.gz: 785c02513e86678da08ae90a634fb2f8e3ffc2f043da72f2d45ba1a478c31064
4
+ data.tar.gz: fe3bdf9e103a93c72f499635110cfa338df7b52e0cd0ab85a4ebeff8a064079c
5
5
  SHA512:
6
- metadata.gz: 6326bd9092d6dbccb09bcc8cfcf9e1157c59b27def4471777bdb509e438328a0faefa9d0d36d7ebc46528fb990a8a9c17f2b07d339144fdfb8e4e37d0a5dc9e2
7
- data.tar.gz: ddf91b7602221a4ab45490971a62ff279f1cc14963f185193496c8c75bb61fed67fef00ba489ac9ab6f3d8f880ec82367530870cd3f0c2b6ad21186b348079bd
6
+ metadata.gz: 8f824861e63e105b6a6f0238ba7a80065b8318ab29c7ac66416597ba1273698d0c5ff9c972b7066e6477576c643099765fbb056b8bdcc4525bd30797be7e6035
7
+ data.tar.gz: 0db138b90a58c3ac211da7f15f412c080ce38a35c27c5adb1cd890def49dc4dd87c8a0c4c6222599573abbf47158b54937598c19fb5da05edb62852a452178e7
data/README.md CHANGED
@@ -415,13 +415,17 @@ if (typeof proscenium.env?.UNKNOWN !== "undefined") {
415
415
 
416
416
  ## i18n
417
417
 
418
- Basic support is provided for importing your Rails locale files from `config/locales/*.yml`, exporting them as JSON.
418
+ Support is provided for importing your Rails locale files from `config/locales/*.yml`, exporting them as JSON.
419
419
 
420
420
  ```js
421
421
  import translations from "proscenium/i18n";
422
422
  // translations.en.*
423
423
  ```
424
424
 
425
+ If you have multiple locale files, they will be merged together. into one json object.
426
+
427
+ Note that because it is assumed that you will be consuming these translations in the browser, all keys are converted to camelCase, as per the JavaScript conventions.
428
+
425
429
  ## Javascript
426
430
 
427
431
  By default, Proscenium's output will take advantage of all modern JS features from the ES2022 spec and earlier. For example, `a !== void 0 && a !== null ? a : b` will become `a ?? b` when minifying (enabled by default in production), which makes use of syntax from the ES2020 version of JavaScript. Any syntax feature that is not supported by ES2020 will be transformed into older JavaScript syntax that is more widely supported.
@@ -23,6 +23,7 @@ module Proscenium
23
23
 
24
24
  attach_function :build_to_string, [
25
25
  :string, # Path or entry point.
26
+ :string, # cache_query_string.
26
27
  :pointer # Config as JSON.
27
28
  ], Result.by_value
28
29
 
@@ -58,8 +59,8 @@ module Proscenium
58
59
  end
59
60
  end
60
61
 
61
- def self.build_to_string(path, root: nil)
62
- new(root:).build_to_string(path)
62
+ def self.build_to_string(path, cache_query_string: '', root: nil)
63
+ new(root:).build_to_string(path, cache_query_string:)
63
64
  end
64
65
 
65
66
  def self.resolve(path, root: nil)
@@ -80,14 +81,15 @@ module Proscenium
80
81
  CodeSplitting: Proscenium.config.code_splitting,
81
82
  RubyGems: Proscenium::BundledGems.paths,
82
83
  Bundle: Proscenium.config.bundle,
83
- QueryString: cache_query_string,
84
+ Aliases: Proscenium.config.aliases,
85
+ QueryString: Proscenium.config.cache_query_string.presence || '',
84
86
  Debug: Proscenium.config.debug
85
87
  }.to_json)
86
88
  end
87
89
 
88
- def build_to_string(path)
90
+ def build_to_string(path, cache_query_string: '')
89
91
  ActiveSupport::Notifications.instrument('build.proscenium', identifier: path) do
90
- result = Request.build_to_string(path, @request_config)
92
+ result = Request.build_to_string(path, cache_query_string, @request_config)
91
93
 
92
94
  raise BuildError, result[:response] unless result[:success]
93
95
 
@@ -114,10 +116,6 @@ module Proscenium
114
116
  ENV.slice(*Proscenium.config.env_vars + Proscenium::DEFAULT_ENV_VARS)
115
117
  end
116
118
 
117
- def cache_query_string
118
- Proscenium.config.cache_query_string.presence || ''
119
- end
120
-
121
119
  def gem_root
122
120
  Pathname.new(__dir__).join('..', '..').to_s
123
121
  end
Binary file
@@ -90,7 +90,7 @@ extern void reset_config();
90
90
  // - path - The path to build relative to `root`.
91
91
  // - config
92
92
  //
93
- extern struct Result build_to_string(char* filePath, char* configJson);
93
+ extern struct Result build_to_string(char* filePath, char* cacheQueryString, char* configJson);
94
94
 
95
95
  // Resolve the given `path` relative to the `root`.
96
96
  //
@@ -98,7 +98,7 @@ module Proscenium
98
98
  end
99
99
 
100
100
  # Ensures extensions with more than one dot are handled correctly.
101
- filepath = filepath.sub_ext('')
101
+ filepath = filepath.sub_ext('').sub_ext('')
102
102
 
103
103
  sideloaded = []
104
104
 
@@ -40,6 +40,17 @@ module Proscenium
40
40
  @path_to_build ||= @request.path[1..]
41
41
  end
42
42
 
43
+ def cache_query_string
44
+ @cache_query_string ||= begin
45
+ params = @request.query_parameters
46
+ if params.one? && params.first[0] != '' && params.first[1].nil?
47
+ params.keys.first
48
+ else
49
+ Proscenium.config.cache_query_string
50
+ end
51
+ end.presence || ''
52
+ end
53
+
43
54
  def sourcemap?
44
55
  @request.path.ends_with?('.map')
45
56
  end
@@ -86,7 +97,7 @@ module Proscenium
86
97
  response.content_type = content_type
87
98
  response.etag = result[:content_hash]
88
99
 
89
- if Proscenium.config.cache_query_string && Proscenium.config.cache_max_age
100
+ if !cache_query_string.blank? && Proscenium.config.cache_max_age
90
101
  response.cache! Proscenium.config.cache_max_age
91
102
  end
92
103
 
@@ -20,7 +20,7 @@ module Proscenium
20
20
  end
21
21
 
22
22
  def attempt
23
- render_response Builder.build_to_string(path_to_build)
23
+ render_response Builder.build_to_string(path_to_build, cache_query_string:)
24
24
  rescue Builder::CompileError => e
25
25
  raise self.class::CompileError, { file: @request.fullpath, detail: e.message }, caller
26
26
  end
@@ -13,10 +13,6 @@ module Proscenium
13
13
 
14
14
  def initialize(app)
15
15
  @app = app
16
-
17
- chunks_path = Rails.public_path.join('assets').to_s
18
- headers = Rails.application.config.public_file_server.headers || {}
19
- @chunk_handler = ::ActionDispatch::FileHandler.new(chunks_path, headers:)
20
16
  end
21
17
 
22
18
  def call(env)
@@ -24,23 +20,19 @@ module Proscenium
24
20
 
25
21
  return @app.call(env) if !request.get? && !request.head?
26
22
 
23
+ # If this is a request for an asset chunk, we want to serve it with a very long
24
+ # cache lifetime, since these are content-hashed and will never change.
27
25
  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
26
+ ::ActionDispatch::FileHandler.new(
27
+ Rails.public_path.join('assets').to_s,
28
+ headers: {
29
+ 'Cache-Control' => "public, max-age=#{100.years}, immutable",
30
+ 'etag' => request.path.match(/-\$([a-z0-9]+)\$/i)[1]
31
+ }
32
+ ).attempt(env) || @app.call(env)
33
+ else
34
+ attempt(request) || @app.call(env)
41
35
  end
42
-
43
- attempt(request) || @app.call(env)
44
36
  end
45
37
 
46
38
  private
@@ -9,11 +9,11 @@ module Proscenium
9
9
  result = super
10
10
  return result if !view.controller || !Proscenium.config.side_load
11
11
 
12
- to_sideload = if template.respond_to?(:virtual_path) &&
12
+ to_sideload = if template.respond_to?(:identifier) &&
13
13
  template.respond_to?(:type) && template.type == :html
14
14
  template
15
15
  end
16
- if to_sideload
16
+ if to_sideload && view.controller.respond_to?(:sideload_assets_options)
17
17
  options = view.controller.sideload_assets_options
18
18
  layout = find_layout(layout_name, locals.keys, [formats.first])
19
19
  sideload_template_assets layout, view.controller, options if layout
@@ -24,6 +24,8 @@ module Proscenium
24
24
  end
25
25
 
26
26
  def sideload_template_assets(tpl, controller, options)
27
+ return unless (tpl_path = Pathname.new(tpl.identifier)).file?
28
+
27
29
  options = {} if options.nil?
28
30
  options = { js: options, css: options } unless options.is_a?(Hash)
29
31
 
@@ -40,7 +42,7 @@ module Proscenium
40
42
  options[k] = controller.instance_eval(&options[k]) if options[k].is_a?(Proc)
41
43
  end
42
44
 
43
- Importer.sideload Rails.root.join("app/views/#{tpl.virtual_path}"), **options
45
+ Importer.sideload tpl_path, **options
44
46
  end
45
47
  end
46
48
 
@@ -52,8 +54,9 @@ module Proscenium
52
54
 
53
55
  return result if !view.controller || !Proscenium.config.side_load
54
56
 
55
- if template.respond_to?(:virtual_path) &&
56
- template.respond_to?(:type) && template.type == :html
57
+ if template.respond_to?(:identifier) &&
58
+ template.respond_to?(:type) && template.type == :html &&
59
+ view.controller.respond_to?(:sideload_assets_options)
57
60
  options = view.controller.sideload_assets_options
58
61
  sideload_template_assets layout, options if layout
59
62
  sideload_template_assets template, options
@@ -63,6 +66,8 @@ module Proscenium
63
66
  end
64
67
 
65
68
  def sideload_template_assets(tpl, options)
69
+ return unless (tpl_path = Pathname.new(tpl.identifier)).file?
70
+
66
71
  options = {} if options.nil?
67
72
  options = { js: options, css: options } unless options.is_a?(Hash)
68
73
 
@@ -79,7 +84,7 @@ module Proscenium
79
84
  options[k] = controller.instance_eval(&options[k]) if options[k].is_a?(Proc)
80
85
  end
81
86
 
82
- Importer.sideload Rails.root.join("app/views/#{tpl.virtual_path}"), **options
87
+ Importer.sideload tpl_path, **options
83
88
  end
84
89
  end
85
90
  end
@@ -18,6 +18,8 @@ module Proscenium
18
18
  config.proscenium.cache_query_string = Rails.env.production? && ENV.fetch('REVISION', nil)
19
19
  config.proscenium.cache_max_age = 2_592_000 # 30 days
20
20
 
21
+ config.proscenium.aliases = {}
22
+
21
23
  # List of environment variable names that should be passed to the builder, which will then be
22
24
  # passed to esbuild's `Define` option. Being explicit about which environment variables are
23
25
  # defined means a faster build, as esbuild will have less to do.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Proscenium
4
- VERSION = '0.19.0'
4
+ VERSION = '0.21.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.19.0
4
+ version: 0.21.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-09-08 00:00:00.000000000 Z
11
+ date: 2025-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi