isomorfeus-asset-manager 0.14.9 → 0.14.13

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: 72c3557faab5046cf4a3f166cde680d0e4cd00d4829d60e036f466c6f69dcd5f
4
- data.tar.gz: 42198b62586fa62d3516ccf553b79b415dd77830cadd40631a66c9c252f9f6b0
3
+ metadata.gz: e6df344a7cb61a035481d5f3c40716027d0b738ba935f8777ac32e2a5a68128d
4
+ data.tar.gz: 60b9863456423a6de7dba3533c36a65f186ecfa73637747fb18d8fe369b0d078
5
5
  SHA512:
6
- metadata.gz: b8ec3a05a2caa23313493e65b5500ec4e11203e97518531b753550e02f37c2b12117c104a4e2a4769c40696caa83064050a3b1dcf96ca92a4751b040f87ecd0c
7
- data.tar.gz: 3d78711a4350ea69d54ca3426df1886dd39c8249e7be67b396e3d253b5f3bcdd0cc39d7f1caf2fee0e499a4ff086f1e8fc730cb0ad9c7ec0b465a2d64cd8e370
6
+ metadata.gz: 9812fc459b7874bd1934f8f0a71becb77cdd716beec36ef446489c30e430d7fccde80ecb3bdb6cfe4227b612dc3cf4830f3c58d2ec98cfbbaed0b57cb883874d
7
+ data.tar.gz: c2d17965c1b479219c824ffb29116f87b9a5c8c4df7758f8f67d89e340c5cf57933fee47e2df5483c154bae92e2ebdf32a3f429ea4b3e3b6fa1c3f154f08f5e3
data/README.md CHANGED
@@ -12,4 +12,4 @@ No need to install esbuild separately, everything bundled ready to go.
12
12
  However, if within the project the 'esbuild' npm package is installed in node_modules, that version will be used instead.
13
13
 
14
14
  ### Community and Support
15
- At the [Isomorfeus Framework Project](http://isomorfeus.com)
15
+ At the [Isomorfeus Framework Project](https://isomorfeus.com)
@@ -1,28 +1,36 @@
1
1
  module Isomorfeus
2
2
  class AssetManager
3
3
  class Asset
4
- attr_reader :bundle, :bundle_size
5
- attr_reader :bundle_gz, :bundle_gz_size
6
- attr_reader :bundle_map, :bundle_map_size
7
- attr_reader :bundle_map_gz, :bundle_map_gz_size
8
- attr_reader :css, :css_size
9
- attr_reader :css_gz, :css_gz_size
10
- attr_reader :css_map, :css_map_size
11
- attr_reader :css_map_gz, :css_map_gz_size
12
- attr_reader :mtime, :ruby_imports, :target
13
- attr_reader :mutex
4
+ class << self
5
+ alias_method :_original_new, :new
6
+ def new(target = :browser)
7
+ return BrowserAsset.new if target == :browser
8
+ return NodeAsset.new if target == :node
9
+ raise "unknown target #{traget}"
10
+ end
11
+ end
12
+
13
+ attr_reader :bundle_ruby_modules, :hash, :target
14
+ attr_reader :mtime, :js_imports, :ruby_imports, :mutex
14
15
 
15
16
  def initialize(target = :browser)
16
- @mutex = Mutex.new
17
- raise "Unknown asset target!" unless %i[browser node].include?(target)
18
17
  @target = target
18
+ @mutex = Mutex.new
19
19
  @bundled = false
20
- @css_bundled = false
21
- @ruby_compiled = false
20
+ @bundle_ruby_modules = {}
21
+ @hash = { css: {}, js: {}}
22
22
  @js_imports = []
23
23
  @ruby_imports = []
24
24
  end
25
25
 
26
+ def browser?
27
+ target == :browser
28
+ end
29
+
30
+ def node?
31
+ target == :node
32
+ end
33
+
26
34
  def add_js_import(*args)
27
35
  @js_imports << Isomorfeus::AssetManager::JsImport.new(*args)
28
36
  end
@@ -31,113 +39,25 @@ module Isomorfeus
31
39
  @ruby_imports << Isomorfeus::AssetManager::RubyImport.new(*args)
32
40
  end
33
41
 
34
- def bundle=(b)
35
- @bundled = true
36
- @bundle = b
37
- @bundle_size = @bundle.size
38
- unless @target == :node
39
- @bundle_gz = Zlib::gzip(b, level: Zlib::BEST_COMPRESSION)
40
- @bundle_gz_size = @bundle_gz.size
41
- end
42
- @bundle
43
- end
44
-
45
- def bundle_map=(m)
46
- @bundled = true
47
- @bundle_map = m
48
- unless @target == :node
49
- @bundle_map_gz = Zlib::gzip(m, level: Zlib::BEST_COMPRESSION)
50
- @bundle_map_gz_size = @bundle_map_gz.size
51
- end
52
- @bundle_map
42
+ def bundle
43
+ @hash[:js][:js][:raw]
53
44
  end
54
45
 
55
46
  def bundled?
56
47
  @bundled
57
48
  end
58
49
 
59
- def css=(b)
50
+ def bundled!
60
51
  @bundled = true
61
- if b
62
- @has_css = true
63
- @css = b
64
- @css_size = @css.size
65
- unless @target == :node
66
- @css_gz = Zlib::gzip(b, level: Zlib::BEST_COMPRESSION)
67
- @css_gz_size = @css_gz.size
68
- end
69
- end
70
- @css
71
52
  end
72
53
 
73
- def css_map=(m)
74
- @bundled = true
75
- if m
76
- @has_css = true
77
- @css_map = m
78
- @css_map_size = @css_map.size
79
- unless @target == :node
80
- @css_map_gz = Zlib::gzip(m, level: Zlib::BEST_COMPRESSION)
81
- @css_map_gz_size = @css_map_gz.size
82
- end
83
- end
84
- @css_map
85
- end
86
-
87
- def has_css?
88
- @has_css
89
- end
90
-
91
- def ruby_modules
92
- @ruby_imports.map(&:module_name)
54
+ def unbundle!
55
+ @bundled = false
93
56
  end
94
57
 
95
58
  def touch
96
59
  @mtime = (Time.now.to_f * (10 ** 9)).to_i
97
60
  end
98
-
99
- def to_s
100
- js = @target == :node ? '' : "if (typeof globalThis !== 'undefined' && typeof global === 'undefined') { globalThis.global = globalThis; }\n"
101
- unless @js_imports.empty?
102
- js << "#{@js_imports.map(&:to_s).join("\n")}"
103
- end
104
- js << "\n" if !@js_imports.empty? && !@ruby_imports.empty?
105
- unless @ruby_imports.empty?
106
- if Isomorfeus.development? && @target == :browser
107
- js << <<~JAVASCRIPT
108
- // Isomorfeus Asset Manager HMR code begin
109
- let ws_protocol = (window.location.protocol == 'https:') ? 'wss:' : 'ws:';
110
- let ws_url = ws_protocol + '//' + window.location.host + "#{Isomorfeus.assets_websocket_path}";
111
- let hmr_ws = new WebSocket(ws_url);
112
- hmr_ws.onmessage = function(event) {
113
- let update = JSON.parse(event.data);
114
- if (typeof update.error !== 'undefined') { console.error(update.error); return; }
115
- if (typeof update.locale !== 'undefined') {
116
- console.log('Updating locale ', update.locale);
117
- try { Opal.Isomorfeus.I18n.Init.$reload_from_server(); }
118
- catch { console.log('Coulnt update locale ', update.locale) }
119
- return;
120
- }
121
- let start_index = 'Opal.modules[\\"'.length;
122
- let end_index = update.javascript.indexOf('"', start_index);
123
- let opal_module_name = update.javascript.substr(start_index, end_index - start_index);
124
- console.log('Updating ', opal_module_name);
125
- if (typeof Opal !== 'undefined' && typeof Opal.require_table !== "undefined" && Opal.require_table['corelib/module']) {
126
- try {
127
- eval(update.javascript);
128
- if (Opal.require_table[opal_module_name]) { Opal.load.call(Opal, opal_module_name); }
129
- else { Opal.require.call(Opal, opal_module_name); }
130
- Opal.Isomorfeus.$force_render();
131
- } catch (e) { console.error(e); return; }
132
- }
133
- }
134
- // Isomorfeus Asset Manager HMR code end
135
- JAVASCRIPT
136
- end
137
- js << "#{@ruby_imports.map(&:to_s).join("\n")}"
138
- end
139
- js
140
- end
141
61
  end
142
62
  end
143
63
  end
@@ -0,0 +1,128 @@
1
+ module Isomorfeus
2
+ class AssetManager
3
+ class BrowserAsset < Asset
4
+ def self.new
5
+ _original_new
6
+ end
7
+
8
+ def initialize(target = :browser)
9
+ super(:browser)
10
+ end
11
+
12
+ def browser?
13
+ true
14
+ end
15
+
16
+ def node?
17
+ false
18
+ end
19
+
20
+ def build_ruby_and_save(asset_key, asset_name, imports_path)
21
+ @ruby_imports.each do |ruby_import|
22
+ module_name = ruby_import.module_name
23
+ asset_dir = File.join(imports_path, asset_name)
24
+ out_file = File.join(asset_dir, "#{module_name}.rb.js")
25
+ next if Isomorfeus.production? && File.exist?(out_file)
26
+ result = Opal::Builder.build(ruby_import.resolved_path, { esm: true })
27
+ js = result.to_s
28
+ if Isomorfeus.production?
29
+ FileUtils.mkdir_p(asset_dir) unless Dir.exist?(asset_dir)
30
+ FileUtils.mkdir_p(File.join(*[asset_dir].concat(module_name.split('/')[0...-1]))) if module_name.include?('/')
31
+ File.write(out_file, js)
32
+ else
33
+ js << "\n//# sourceMappingURL=#{Isomorfeus.assets_path}/#{asset_name}/#{module_name}.rb.js.map\n"
34
+ @bundle_ruby_modules[module_name] = { js: { raw: js }, map: { raw: Oj.dump(result.source_map.as_json, mode: :strict) }}
35
+ end
36
+ end
37
+ end
38
+
39
+ def save_entry(asset_key, asset_name, imports_path)
40
+ entry = File.join(imports_path, asset_key)
41
+ File.write(entry, generate_entry(asset_name))
42
+ entry
43
+ end
44
+
45
+ def bundle_css(asset_name, output_path)
46
+ filename = File.join(output_path, asset_name + '.css')
47
+ @hash[:css][:css] = { raw: File.read(filename) } if File.exist?(filename)
48
+ end
49
+
50
+ def bundle_css_map(asset_name, output_path)
51
+ filename = File.join(output_path, asset_name + '.css.map')
52
+ @hash[:css][:map] = { raw: File.read(filename) } if File.exist?(filename)
53
+ end
54
+
55
+ def bundle_js(asset_key, asset_name, imports_path, output_path)
56
+ js = File.read(File.join(output_path, asset_key))
57
+ js << ruby_imports_to_s(asset_name, imports_path) unless Isomorfeus.production?
58
+ @hash[:js][:js] = { raw: js }
59
+ end
60
+
61
+ def bundle_js_map(asset_key, output_path)
62
+ filename = File.join(output_path, asset_key + '.map')
63
+ @hash[:js][:map] = { raw: File.read(filename) } if File.exist?(filename)
64
+ end
65
+
66
+ def ruby_imports_to_s(asset_name, out_dir)
67
+ s = @ruby_imports.size - 1
68
+ return '' if s < 0
69
+ js = "async function iam_load_ruby_modules() {\n"
70
+ @ruby_imports.each do |import|
71
+ js << import.to_dev_s(asset_name)
72
+ end
73
+ js << "}\niam_load_ruby_modules();\n"
74
+ end
75
+
76
+ def generate_entry(asset_name)
77
+ js = "if (typeof globalThis !== 'undefined' && typeof global === 'undefined') { globalThis.global = globalThis; }\n"
78
+ js << "#{@js_imports.map(&:to_s).join("\n")}"
79
+ if @ruby_imports.any?
80
+ if Isomorfeus.development?
81
+ js << <<~JAVASCRIPT
82
+ // Isomorfeus Asset Manager HMR code begin
83
+ let ws_protocol = (window.location.protocol == 'https:') ? 'wss:' : 'ws:';
84
+ let ws_url = ws_protocol + '//' + window.location.host + "#{Isomorfeus.hmr_websocket_path}";
85
+ let hmr_ws_fun = function() {
86
+ let hmr_ws = new WebSocket(ws_url);
87
+ hmr_ws.onopen = function(event) { console.log("Isomorfeus Asset Manager HMR socket connected"); }
88
+ hmr_ws.onmessage = function(event) {
89
+ let update = JSON.parse(event.data);
90
+ if (typeof update.error !== 'undefined') { console.error(update.error); return; }
91
+ if (typeof update.locale !== 'undefined') {
92
+ console.log('Isomorfeus Asset Manager updating locale ', update.locale);
93
+ try { Opal.Isomorfeus.I18n.Init.$reload_from_server(); }
94
+ catch { console.log('Isomorfeus Asset Manager could not update locale ', update.locale) }
95
+ return;
96
+ }
97
+ let start_index = 'Opal.modules[\\"'.length;
98
+ let end_index = update.javascript.indexOf('"', start_index);
99
+ let opal_module_name = update.javascript.substr(start_index, end_index - start_index);
100
+ console.log('Isomorfeus Asset Manager updating ', opal_module_name);
101
+ if (typeof Opal !== 'undefined' && typeof Opal.require_table !== "undefined" && Opal.require_table['corelib/module']) {
102
+ try {
103
+ window.eval(update.javascript);
104
+ if (Opal.require_table[opal_module_name]) { Opal.load.call(Opal, opal_module_name); }
105
+ else { Opal.require.call(Opal, opal_module_name); }
106
+ Opal.Isomorfeus.$force_render();
107
+ } catch (e) { console.error(e); return; }
108
+ }
109
+ };
110
+ hmr_ws.onclose = function(event) {
111
+ setTimeout(function() {
112
+ console.log("Isomorfeus Asset Manager reconnecting HMR socket");
113
+ hmr_ws_fun();
114
+ }, 2000);
115
+ };
116
+ }
117
+ hmr_ws_fun()
118
+ // Isomorfeus Asset Manager HMR code end
119
+ JAVASCRIPT
120
+ elsif Isomorfeus.production?
121
+ js << "#{@ruby_imports.map { |i| i.to_s(asset_name) }.join("\n")}"
122
+ end
123
+ end
124
+ js
125
+ end
126
+ end
127
+ end
128
+ end
@@ -8,7 +8,7 @@ module Isomorfeus
8
8
  attr_accessor :root
9
9
  attr_accessor :app_root
10
10
  attr_accessor :assets_path
11
- attr_accessor :assets_websocket_path
11
+ attr_accessor :hmr_websocket_path
12
12
  attr_accessor :asset_manager_tmpdir
13
13
  attr_accessor :asset_manager_hmr_channel
14
14
  attr_accessor :asset_manager_hmr_dirs
@@ -67,7 +67,7 @@ module Isomorfeus
67
67
  self.hmr_listener = nil
68
68
  self.asset_manager_hmr_channel = :isomorfeus_asset_manager_module_updates
69
69
  self.asset_manager_hmr_dirs = %w[channels components data locales operations policies]
70
- self.assets_websocket_path = '/_assets_websocket'
70
+ self.hmr_websocket_path = '/_asset_manager_hmr_websocket'
71
71
  self.assets_path = '/assets'
72
72
  self.assets = {
73
73
  'web.js' => Isomorfeus::AssetManager::Asset.new(:browser),
@@ -0,0 +1,56 @@
1
+ module Isomorfeus
2
+ class AssetManager
3
+ class NodeAsset < Asset
4
+ def self.new
5
+ _original_new
6
+ end
7
+
8
+ def initialize(target = :node)
9
+ super(:node)
10
+ end
11
+
12
+ def browser?
13
+ false
14
+ end
15
+
16
+ def node?
17
+ true
18
+ end
19
+
20
+ def bundle
21
+ @hash[:js][:js][:raw]
22
+ end
23
+
24
+ def build_ruby_and_save(asset_key, asset_name, imports_path)
25
+ @ruby_imports.each do |ruby_import|
26
+ module_name = ruby_import.module_name
27
+ asset_dir = File.join(imports_path, asset_name)
28
+ out_file = File.join(asset_dir, "#{module_name}.rb.js")
29
+ next if Isomorfeus.production? && File.exist?(out_file)
30
+ result = Opal::Builder.build(ruby_import.resolved_path, { esm: true })
31
+ FileUtils.mkdir_p(asset_dir) unless Dir.exist?(asset_dir)
32
+ FileUtils.mkdir_p(File.join(*[asset_dir].concat(module_name.split('/')[0...-1]))) if module_name.include?('/')
33
+ File.write(out_file, result.to_s)
34
+ end
35
+ nil
36
+ end
37
+
38
+ def save_entry(asset_key, asset_name, imports_path)
39
+ entry = File.join(imports_path, asset_key)
40
+ File.write(entry, generate_entry(asset_name))
41
+ entry
42
+ end
43
+
44
+ def bundle_js(asset_key, asset_name, imports_path, output_path)
45
+ js = File.read(File.join(output_path, asset_key))
46
+ @hash[:js][:js] = { raw: js }
47
+ end
48
+
49
+ def generate_entry(asset_name)
50
+ js = ''
51
+ js << "#{@js_imports.map(&:to_s).join("\n")}"
52
+ js << "#{@ruby_imports.map { |i| i.to_s(asset_name) }.join("\n")}"
53
+ end
54
+ end
55
+ end
56
+ end
@@ -4,12 +4,13 @@ module Isomorfeus
4
4
  class AssetManager
5
5
  class RackMiddleware
6
6
  WS_RESPONSE = [0, {}, []].freeze
7
+ C_ENCODINGS = %w[br gzip].freeze
8
+
7
9
  attr_reader :asset_manager
8
10
 
9
11
  def initialize(app)
10
12
  @app = app
11
13
  @asset_manager = Isomorfeus::AssetManager.new
12
- @compressible_types = %w[application/javascript text/javascript text/css]
13
14
  if Isomorfeus.assets_path.end_with?('/')
14
15
  @assets_path = Isomorfeus.assets_path
15
16
  @assets_path_size = @assets_path.size
@@ -25,88 +26,81 @@ module Isomorfeus
25
26
  path_info = env['PATH_INFO']
26
27
  if path_info.start_with?(@assets_path)
27
28
 
28
- if path_info.end_with?('.js')
29
- # get js
30
- asset_key = path_info[@assets_path_size..-1]
31
- if Isomorfeus.assets.key?(asset_key)
29
+ if !Isomorfeus.production?
30
+ if path_info.end_with?('.rb.js')
31
+ asset_key_module_name = path_info[@assets_path_size..-7]
32
+ asset_key, module_name = asset_key_module_name.split('/')
33
+ asset_key += '.js'
34
+ if Isomorfeus.assets.key?(asset_key)
35
+ asset = Isomorfeus.assets[asset_key]
36
+ if asset && asset.browser?
37
+ if asset.bundle_ruby_modules.key?(module_name)
38
+ headers = { Rack::CONTENT_TYPE => 'application/javascript' }
39
+ asset_manager.transition(asset_key, asset)
40
+ return [200, headers, get_content(env, headers, asset, asset_key, asset.bundle_ruby_modules[module_name][:js])]
41
+ end
42
+ end
43
+ end
44
+
45
+ elsif path_info.end_with?('.rb.js.map')
46
+ asset_key_module_name = path_info[@assets_path_size..-11]
47
+ asset_key, module_name = asset_key_module_name.split('/')
48
+ asset_key += '.js'
32
49
  asset = Isomorfeus.assets[asset_key]
33
- if asset && asset.target != :node
34
- asset_manager.transition(asset_key, asset)
35
- headers = {}
36
- headers['Last-Modified'] = asset.mtime
37
- headers[Rack::CONTENT_TYPE] = 'application/javascript'
38
- if should_gzip?(env)
39
- headers['Content-Encoding'] = "gzip"
40
- headers[Rack::CONTENT_LENGTH] = asset.bundle_gz_size
41
- return [200, headers, asset.bundle_gz]
42
- else
43
- headers[Rack::CONTENT_LENGTH] = asset.bundle_size
44
- return [200, headers, asset.bundle]
50
+ if asset && asset.browser?
51
+ if asset.bundle_ruby_modules.key?(module_name)
52
+ headers = { Rack::CONTENT_TYPE => 'application/json' }
53
+ asset_manager.transition(asset_key, asset)
54
+ return [200, headers, get_content(env, headers, asset, asset_key, asset.bundle_ruby_modules[module_name][:map])]
45
55
  end
46
56
  end
57
+
58
+ elsif path_info.end_with?('.js.map')
59
+ asset_key = path_info[@assets_path_size..-5]
60
+ asset = Isomorfeus.assets[asset_key]
61
+ if asset && asset.browser?
62
+ headers = { Rack::CONTENT_TYPE => 'application/json' }
63
+ asset_manager.transition(asset_key, asset)
64
+ return [200, headers, get_content(env, headers, asset, asset_key, asset.hash[:js][:map])]
65
+ end
66
+
67
+ elsif path_info.end_with?('.css.map')
68
+ # get css source map
69
+ asset_key = path_info[@assets_path_size..-9] + '.js'
70
+ asset = Isomorfeus.assets[asset_key]
71
+ if asset && asset.browser?
72
+ headers = { Rack::CONTENT_TYPE => 'application/json' }
73
+ asset_manager.transition(asset_key, asset)
74
+ content = get_content(env, headers, asset, asset_key, asset.hash[:css][:map])
75
+ return [200, headers, content]
76
+ end
47
77
  end
78
+ end
48
79
 
49
- elsif path_info.end_with?('.js.map')
50
- # get js source map
51
- asset_key = path_info[@assets_path_size..-5]
52
- asset = Isomorfeus.assets[asset_key]
53
- if asset && asset.target != :node
54
- asset_manager.transition(asset_key, asset) unless asset.bundled?
55
- headers = {}
56
- headers['Last-Modified'] = asset.mtime
57
- headers[Rack::CONTENT_TYPE] = 'application/json'
58
- if should_gzip?(env)
59
- headers['Content-Encoding'] = "gzip"
60
- headers[Rack::CONTENT_LENGTH] = asset.bundle_map_gz_size
61
- return [200, headers, asset.bundle_map_gz]
62
- else
63
- headers[Rack::CONTENT_LENGTH] = asset.bundle_map_size
64
- return [200, headers, asset.bundle_map]
80
+ if path_info.end_with?('.js')
81
+ asset_key = path_info[@assets_path_size..-1]
82
+ if Isomorfeus.assets.key?(asset_key)
83
+ asset = Isomorfeus.assets[asset_key]
84
+ if asset && asset.browser?
85
+ headers = { Rack::CONTENT_TYPE => 'application/javascript' }
86
+ asset_manager.transition(asset_key, asset)
87
+ return [200, headers, get_content(env, headers, asset, asset_key, asset.hash[:js][:js])]
65
88
  end
66
89
  end
67
90
 
68
91
  elsif path_info.end_with?('.css')
69
- # get css
70
92
  asset_key = path_info[@assets_path_size..-5] + '.js'
71
93
  asset = Isomorfeus.assets[asset_key]
72
- if asset && asset.target != :node
94
+ if asset && asset.browser?
95
+ headers = { Rack::CONTENT_TYPE => 'text/css' }
73
96
  asset_manager.transition(asset_key, asset)
74
- headers = {}
75
- headers['Last-Modified'] = asset.mtime
76
- headers[Rack::CONTENT_TYPE] = 'text/css'
77
- if should_gzip?(env)
78
- headers['Content-Encoding'] = "gzip"
79
- headers[Rack::CONTENT_LENGTH] = asset.css_gz_size
80
- return [200, headers, asset.css_gz]
81
- else
82
- headers[Rack::CONTENT_LENGTH] = asset.css_size
83
- return [200, headers, asset.css]
84
- end
85
- end
86
-
87
- elsif path_info.end_with?('.css.map')
88
- # get css source map
89
- asset_key = path_info[@assets_path_size..-9] + '.js'
90
- asset = Isomorfeus.assets[asset_key]
91
- if asset && asset.target != :node
92
- asset_manager.transition(asset_key, asset) unless asset.bundled?
93
- headers = {}
94
- headers['Last-Modified'] = asset.mtime
95
- headers[Rack::CONTENT_TYPE] = 'application/json'
96
- if should_gzip?(env)
97
- headers['Content-Encoding'] = "gzip"
98
- headers[Rack::CONTENT_LENGTH] = asset.css_map_gz_size
99
- return [200, headers, asset.css_map_gz]
100
- else
101
- headers[Rack::CONTENT_LENGTH] = asset.css_map_size
102
- return [200, headers, asset.css_map]
103
- end
97
+ return [200, headers, get_content(env, headers, asset, asset_key, asset.hash[:css][:css])]
104
98
  end
105
99
  end
106
100
 
107
101
  return [404, {}, 'not found']
108
102
  # hot reloading subscription
109
- elsif Isomorfeus.development? && path_info == Isomorfeus.assets_websocket_path
103
+ elsif Isomorfeus.development? && path_info == Isomorfeus.hmr_websocket_path
110
104
  if env['rack.upgrade?'] == :websocket
111
105
  env['rack.upgrade'] = Isomorfeus::AssetManager::ServerSocketProcessor.new
112
106
  end
@@ -119,11 +113,29 @@ module Isomorfeus
119
113
  @app.call(env)
120
114
  end
121
115
 
122
- def should_gzip?(env)
123
- return true if env.key?('HTTP_ACCEPT_ENCODING') && env['HTTP_ACCEPT_ENCODING'].match?(/\bgzip\b/)
124
- return false if /\bno-transform\b/.match?(env[Rack::CACHE_CONTROL].to_s) || env['Content-Encoding']&.!~(/\bidentity\b/)
125
- return false if @compressible_types && !(env.key?(Rack::CONTENT_TYPE) && @compressible_types.include?(env[Rack::CONTENT_TYPE][/[^;]*/]))
126
- true
116
+ def get_content(env, headers, asset, asset_key, content_hash)
117
+ request = Rack::Request.new(env)
118
+ best_encoding = Rack::Utils.select_best_encoding(C_ENCODINGS, request.accept_encoding)
119
+ content = ''
120
+ case best_encoding
121
+ when 'gzip'
122
+ headers['Content-Encoding'] = "gzip"
123
+ unless content_hash.key?(:gzip)
124
+ asset.mutex.synchronize { content_hash[:gzip] = Zlib::gzip(content_hash[:raw], level: Zlib::BEST_COMPRESSION) unless content_hash.key?(:gzip) }
125
+ end
126
+ content = content_hash[:gzip]
127
+ when 'br'
128
+ headers['Content-Encoding'] = "br"
129
+ unless content_hash.key?(:br)
130
+ asset.mutex.synchronize { content_hash[:br] = Brotli.deflate(content_hash[:raw], quality: Isomorfeus.production? ? 9 : 5) unless content_hash.key?(:br) }
131
+ end
132
+ content = content_hash[:br]
133
+ else
134
+ content = content_hash[:raw]
135
+ end
136
+ headers[Rack::CONTENT_LENGTH] = content.size
137
+ headers['Last-Modified'] = asset.mtime
138
+ content
127
139
  end
128
140
  end
129
141
  end
@@ -13,8 +13,12 @@ module Isomorfeus
13
13
  @resolved_path ||= resolve_path
14
14
  end
15
15
 
16
- def to_s
17
- "import(\"./#{@module_name}.js\");\n"
16
+ def to_s(asset_name)
17
+ "import(\"./#{asset_name}/#{@module_name}.rb.js\");\n"
18
+ end
19
+
20
+ def to_dev_s(asset_name)
21
+ "await import(\"#{Isomorfeus.assets_path}/#{asset_name}/#{@module_name}.rb.js\");\n"
18
22
  end
19
23
 
20
24
  private
@@ -1,5 +1,5 @@
1
1
  module Isomorfeus
2
2
  class AssetManager
3
- VERSION = '0.14.9'
3
+ VERSION = '0.14.13'
4
4
  end
5
5
  end