isomorfeus-asset-manager 0.14.12 → 0.14.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/isomorfeus/asset_manager/asset.rb +27 -144
- data/lib/isomorfeus/asset_manager/browser_asset.rb +128 -0
- data/lib/isomorfeus/asset_manager/config.rb +2 -2
- data/lib/isomorfeus/asset_manager/node_asset.rb +56 -0
- data/lib/isomorfeus/asset_manager/rack_middleware.rb +49 -84
- data/lib/isomorfeus/asset_manager/ruby_import.rb +3 -3
- data/lib/isomorfeus/asset_manager/version.rb +1 -1
- data/lib/isomorfeus/asset_manager.rb +21 -76
- data/lib/isomorfeus-asset-manager.rb +4 -0
- data/node_modules/.package-lock.json +3 -3
- data/node_modules/esbuild-wasm/esbuild.wasm +0 -0
- data/node_modules/esbuild-wasm/esm/browser.js +11 -5
- data/node_modules/esbuild-wasm/esm/browser.min.js +2 -2
- data/node_modules/esbuild-wasm/lib/browser.js +10 -5
- data/node_modules/esbuild-wasm/lib/browser.min.js +2 -2
- data/node_modules/esbuild-wasm/lib/main.js +14 -8
- data/node_modules/esbuild-wasm/package.json +1 -1
- data/node_modules/esbuild-wasm/wasm_exec.js +4 -1
- data/package.json +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6df344a7cb61a035481d5f3c40716027d0b738ba935f8777ac32e2a5a68128d
|
4
|
+
data.tar.gz: 60b9863456423a6de7dba3533c36a65f186ecfa73637747fb18d8fe369b0d078
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9812fc459b7874bd1934f8f0a71becb77cdd716beec36ef446489c30e430d7fccde80ecb3bdb6cfe4227b612dc3cf4830f3c58d2ec98cfbbaed0b57cb883874d
|
7
|
+
data.tar.gz: c2d17965c1b479219c824ffb29116f87b9a5c8c4df7758f8f67d89e340c5cf57933fee47e2df5483c154bae92e2ebdf32a3f429ea4b3e3b6fa1c3f154f08f5e3
|
@@ -1,180 +1,63 @@
|
|
1
1
|
module Isomorfeus
|
2
2
|
class AssetManager
|
3
3
|
class Asset
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
attr_reader :
|
14
|
-
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
|
15
15
|
|
16
16
|
def initialize(target = :browser)
|
17
|
-
@mutex = Mutex.new
|
18
|
-
raise "Unknown asset target!" unless %i[browser node].include?(target)
|
19
17
|
@target = target
|
18
|
+
@mutex = Mutex.new
|
20
19
|
@bundled = false
|
21
|
-
@
|
22
|
-
@
|
20
|
+
@bundle_ruby_modules = {}
|
21
|
+
@hash = { css: {}, js: {}}
|
23
22
|
@js_imports = []
|
24
23
|
@ruby_imports = []
|
25
24
|
end
|
26
25
|
|
27
|
-
def
|
28
|
-
|
26
|
+
def browser?
|
27
|
+
target == :browser
|
29
28
|
end
|
30
29
|
|
31
|
-
def
|
32
|
-
|
30
|
+
def node?
|
31
|
+
target == :node
|
33
32
|
end
|
34
33
|
|
35
|
-
def
|
36
|
-
@
|
37
|
-
@bundle = b
|
38
|
-
@bundle_size = @bundle.size
|
39
|
-
unless @target == :node
|
40
|
-
@bundle_gz = Zlib::gzip(b, level: Zlib::BEST_COMPRESSION)
|
41
|
-
@bundle_gz_size = @bundle_gz.size
|
42
|
-
end
|
43
|
-
@bundle
|
34
|
+
def add_js_import(*args)
|
35
|
+
@js_imports << Isomorfeus::AssetManager::JsImport.new(*args)
|
44
36
|
end
|
45
37
|
|
46
|
-
def
|
47
|
-
@
|
48
|
-
@bundle_map = m
|
49
|
-
unless @target == :node
|
50
|
-
@bundle_map_gz = Zlib::gzip(m, level: Zlib::BEST_COMPRESSION)
|
51
|
-
@bundle_map_gz_size = @bundle_map_gz.size
|
52
|
-
end
|
53
|
-
@bundle_map
|
38
|
+
def add_ruby_import(*args)
|
39
|
+
@ruby_imports << Isomorfeus::AssetManager::RubyImport.new(*args)
|
54
40
|
end
|
55
41
|
|
56
|
-
def
|
57
|
-
@
|
58
|
-
@bundle_ruby_modules = m
|
59
|
-
if !Isomorfeus.production? && @target != :node
|
60
|
-
@bundle_ruby_modules.each do |key, mod_hash|
|
61
|
-
mod_hash[:js_size] = mod_hash[:js].size
|
62
|
-
mod_hash[:js_gz] = Zlib::gzip(mod_hash[:js], level: Zlib::BEST_COMPRESSION)
|
63
|
-
mod_hash[:js_gz_size] = mod_hash[:js_gz].size
|
64
|
-
mod_hash[:map_size] = mod_hash[:map].size
|
65
|
-
mod_hash[:map_gz] = Zlib::gzip(mod_hash[:map], level: Zlib::BEST_COMPRESSION)
|
66
|
-
mod_hash[:map_gz_size] = mod_hash[:map_gz].size
|
67
|
-
end
|
68
|
-
end
|
69
|
-
@bundle_ruby_modules
|
42
|
+
def bundle
|
43
|
+
@hash[:js][:js][:raw]
|
70
44
|
end
|
71
45
|
|
72
46
|
def bundled?
|
73
47
|
@bundled
|
74
48
|
end
|
75
49
|
|
76
|
-
def
|
50
|
+
def bundled!
|
77
51
|
@bundled = true
|
78
|
-
if b
|
79
|
-
@has_css = true
|
80
|
-
@css = b
|
81
|
-
@css_size = @css.size
|
82
|
-
unless @target == :node
|
83
|
-
@css_gz = Zlib::gzip(b, level: Zlib::BEST_COMPRESSION)
|
84
|
-
@css_gz_size = @css_gz.size
|
85
|
-
end
|
86
|
-
end
|
87
|
-
@css
|
88
|
-
end
|
89
|
-
|
90
|
-
def css_map=(m)
|
91
|
-
@bundled = true
|
92
|
-
if m
|
93
|
-
@has_css = true
|
94
|
-
@css_map = m
|
95
|
-
@css_map_size = @css_map.size
|
96
|
-
unless @target == :node
|
97
|
-
@css_map_gz = Zlib::gzip(m, level: Zlib::BEST_COMPRESSION)
|
98
|
-
@css_map_gz_size = @css_map_gz.size
|
99
|
-
end
|
100
|
-
end
|
101
|
-
@css_map
|
102
|
-
end
|
103
|
-
|
104
|
-
def has_css?
|
105
|
-
@has_css
|
106
52
|
end
|
107
53
|
|
108
|
-
def
|
109
|
-
@
|
110
|
-
end
|
111
|
-
|
112
|
-
def ruby_imports_to_s(asset_name)
|
113
|
-
s = @ruby_imports.size - 1
|
114
|
-
return '' if s < 0
|
115
|
-
js = "async function iam_load_ruby_modules() {\n"
|
116
|
-
@ruby_imports.each do |import|
|
117
|
-
js << ' await ' << import.to_dev_s(asset_name)
|
118
|
-
end
|
119
|
-
js << "}\niam_load_ruby_modules();\n"
|
54
|
+
def unbundle!
|
55
|
+
@bundled = false
|
120
56
|
end
|
121
57
|
|
122
58
|
def touch
|
123
59
|
@mtime = (Time.now.to_f * (10 ** 9)).to_i
|
124
60
|
end
|
125
|
-
|
126
|
-
def to_s
|
127
|
-
js = @target == :node ? '' : "if (typeof globalThis !== 'undefined' && typeof global === 'undefined') { globalThis.global = globalThis; }\n"
|
128
|
-
unless @js_imports.empty?
|
129
|
-
js << "#{@js_imports.map(&:to_s).join("\n")}"
|
130
|
-
end
|
131
|
-
js << "\n" if !@js_imports.empty? && !@ruby_imports.empty?
|
132
|
-
unless @ruby_imports.empty?
|
133
|
-
if Isomorfeus.development? && @target == :browser
|
134
|
-
js << <<~JAVASCRIPT
|
135
|
-
// Isomorfeus Asset Manager HMR code begin
|
136
|
-
let ws_protocol = (window.location.protocol == 'https:') ? 'wss:' : 'ws:';
|
137
|
-
let ws_url = ws_protocol + '//' + window.location.host + "#{Isomorfeus.assets_websocket_path}";
|
138
|
-
let hmr_ws_fun = function() {
|
139
|
-
let hmr_ws = new WebSocket(ws_url);
|
140
|
-
hmr_ws.onopen = function(event) { console.log("Isomorfeus Asset Manager HMR socket connected"); }
|
141
|
-
hmr_ws.onmessage = function(event) {
|
142
|
-
let update = JSON.parse(event.data);
|
143
|
-
if (typeof update.error !== 'undefined') { console.error(update.error); return; }
|
144
|
-
if (typeof update.locale !== 'undefined') {
|
145
|
-
console.log('Isomorfeus Asset Manager updating locale ', update.locale);
|
146
|
-
try { Opal.Isomorfeus.I18n.Init.$reload_from_server(); }
|
147
|
-
catch { console.log('Isomorfeus Asset Manager could not update locale ', update.locale) }
|
148
|
-
return;
|
149
|
-
}
|
150
|
-
let start_index = 'Opal.modules[\\"'.length;
|
151
|
-
let end_index = update.javascript.indexOf('"', start_index);
|
152
|
-
let opal_module_name = update.javascript.substr(start_index, end_index - start_index);
|
153
|
-
console.log('Isomorfeus Asset Manager updating ', opal_module_name);
|
154
|
-
if (typeof Opal !== 'undefined' && typeof Opal.require_table !== "undefined" && Opal.require_table['corelib/module']) {
|
155
|
-
try {
|
156
|
-
eval(update.javascript);
|
157
|
-
if (Opal.require_table[opal_module_name]) { Opal.load.call(Opal, opal_module_name); }
|
158
|
-
else { Opal.require.call(Opal, opal_module_name); }
|
159
|
-
Opal.Isomorfeus.$force_render();
|
160
|
-
} catch (e) { console.error(e); return; }
|
161
|
-
}
|
162
|
-
};
|
163
|
-
hmr_ws.onclose = function(event) {
|
164
|
-
setTimeout(function() {
|
165
|
-
console.log("Isomorfeus Asset Manager reconnecting HMR socket");
|
166
|
-
hmr_ws_fun();
|
167
|
-
}, 2000);
|
168
|
-
};
|
169
|
-
}
|
170
|
-
hmr_ws_fun()
|
171
|
-
// Isomorfeus Asset Manager HMR code end
|
172
|
-
JAVASCRIPT
|
173
|
-
end
|
174
|
-
js << "#{@ruby_imports.map(&:to_s).join("\n")}" if Isomorfeus.production? || target == :node
|
175
|
-
end
|
176
|
-
js
|
177
|
-
end
|
178
61
|
end
|
179
62
|
end
|
180
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 :
|
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.
|
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
|
@@ -32,20 +33,11 @@ module Isomorfeus
|
|
32
33
|
asset_key += '.js'
|
33
34
|
if Isomorfeus.assets.key?(asset_key)
|
34
35
|
asset = Isomorfeus.assets[asset_key]
|
35
|
-
if asset && asset.
|
36
|
-
asset_manager.transition(asset_key, asset) unless asset.bundled?
|
36
|
+
if asset && asset.browser?
|
37
37
|
if asset.bundle_ruby_modules.key?(module_name)
|
38
|
-
headers = {}
|
39
|
-
|
40
|
-
headers[
|
41
|
-
if should_gzip?(env)
|
42
|
-
headers['Content-Encoding'] = "gzip"
|
43
|
-
headers[Rack::CONTENT_LENGTH] = asset.bundle_ruby_modules[module_name][:js_gz_size]
|
44
|
-
return [200, headers, asset.bundle_ruby_modules[module_name][:js_gz]]
|
45
|
-
else
|
46
|
-
headers[Rack::CONTENT_LENGTH] = asset.bundle_ruby_modules[module_name][:js_size]
|
47
|
-
return [200, headers, asset.bundle_ruby_modules[module_name][:js]]
|
48
|
-
end
|
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])]
|
49
41
|
end
|
50
42
|
end
|
51
43
|
end
|
@@ -55,58 +47,32 @@ module Isomorfeus
|
|
55
47
|
asset_key, module_name = asset_key_module_name.split('/')
|
56
48
|
asset_key += '.js'
|
57
49
|
asset = Isomorfeus.assets[asset_key]
|
58
|
-
if asset && asset.
|
59
|
-
asset_manager.transition(asset_key, asset) unless asset.bundled?
|
50
|
+
if asset && asset.browser?
|
60
51
|
if asset.bundle_ruby_modules.key?(module_name)
|
61
|
-
headers = {}
|
62
|
-
|
63
|
-
headers[
|
64
|
-
if should_gzip?(env)
|
65
|
-
headers['Content-Encoding'] = "gzip"
|
66
|
-
headers[Rack::CONTENT_LENGTH] = asset.bundle_ruby_modules[module_name][:map_gz_size]
|
67
|
-
return [200, headers, asset.bundle_ruby_modules[module_name][:map_gz]]
|
68
|
-
else
|
69
|
-
headers[Rack::CONTENT_LENGTH] = asset.bundle_ruby_modules[module_name][:map_size]
|
70
|
-
return [200, headers, asset.bundle_ruby_modules[module_name][:map]]
|
71
|
-
end
|
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])]
|
72
55
|
end
|
73
56
|
end
|
74
57
|
|
75
58
|
elsif path_info.end_with?('.js.map')
|
76
59
|
asset_key = path_info[@assets_path_size..-5]
|
77
60
|
asset = Isomorfeus.assets[asset_key]
|
78
|
-
if asset && asset.
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
headers[Rack::CONTENT_TYPE] = 'application/json'
|
83
|
-
if should_gzip?(env)
|
84
|
-
headers['Content-Encoding'] = "gzip"
|
85
|
-
headers[Rack::CONTENT_LENGTH] = asset.bundle_map_gz_size
|
86
|
-
return [200, headers, asset.bundle_map_gz]
|
87
|
-
else
|
88
|
-
headers[Rack::CONTENT_LENGTH] = asset.bundle_map_size
|
89
|
-
return [200, headers, asset.bundle_map]
|
90
|
-
end
|
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])]
|
91
65
|
end
|
92
66
|
|
93
67
|
elsif path_info.end_with?('.css.map')
|
94
68
|
# get css source map
|
95
69
|
asset_key = path_info[@assets_path_size..-9] + '.js'
|
96
70
|
asset = Isomorfeus.assets[asset_key]
|
97
|
-
if asset && asset.
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
if should_gzip?(env)
|
103
|
-
headers['Content-Encoding'] = "gzip"
|
104
|
-
headers[Rack::CONTENT_LENGTH] = asset.css_map_gz_size
|
105
|
-
return [200, headers, asset.css_map_gz]
|
106
|
-
else
|
107
|
-
headers[Rack::CONTENT_LENGTH] = asset.css_map_size
|
108
|
-
return [200, headers, asset.css_map]
|
109
|
-
end
|
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]
|
110
76
|
end
|
111
77
|
end
|
112
78
|
end
|
@@ -115,45 +81,26 @@ module Isomorfeus
|
|
115
81
|
asset_key = path_info[@assets_path_size..-1]
|
116
82
|
if Isomorfeus.assets.key?(asset_key)
|
117
83
|
asset = Isomorfeus.assets[asset_key]
|
118
|
-
if asset && asset.
|
84
|
+
if asset && asset.browser?
|
85
|
+
headers = { Rack::CONTENT_TYPE => 'application/javascript' }
|
119
86
|
asset_manager.transition(asset_key, asset)
|
120
|
-
headers
|
121
|
-
headers['Last-Modified'] = asset.mtime
|
122
|
-
headers[Rack::CONTENT_TYPE] = 'application/javascript'
|
123
|
-
if should_gzip?(env)
|
124
|
-
headers['Content-Encoding'] = "gzip"
|
125
|
-
headers[Rack::CONTENT_LENGTH] = asset.bundle_gz_size
|
126
|
-
return [200, headers, asset.bundle_gz]
|
127
|
-
else
|
128
|
-
headers[Rack::CONTENT_LENGTH] = asset.bundle_size
|
129
|
-
return [200, headers, asset.bundle]
|
130
|
-
end
|
87
|
+
return [200, headers, get_content(env, headers, asset, asset_key, asset.hash[:js][:js])]
|
131
88
|
end
|
132
89
|
end
|
133
90
|
|
134
91
|
elsif path_info.end_with?('.css')
|
135
|
-
# get css
|
136
92
|
asset_key = path_info[@assets_path_size..-5] + '.js'
|
137
93
|
asset = Isomorfeus.assets[asset_key]
|
138
|
-
if asset && asset.
|
94
|
+
if asset && asset.browser?
|
95
|
+
headers = { Rack::CONTENT_TYPE => 'text/css' }
|
139
96
|
asset_manager.transition(asset_key, asset)
|
140
|
-
headers
|
141
|
-
headers['Last-Modified'] = asset.mtime
|
142
|
-
headers[Rack::CONTENT_TYPE] = 'text/css'
|
143
|
-
if should_gzip?(env)
|
144
|
-
headers['Content-Encoding'] = "gzip"
|
145
|
-
headers[Rack::CONTENT_LENGTH] = asset.css_gz_size
|
146
|
-
return [200, headers, asset.css_gz]
|
147
|
-
else
|
148
|
-
headers[Rack::CONTENT_LENGTH] = asset.css_size
|
149
|
-
return [200, headers, asset.css]
|
150
|
-
end
|
97
|
+
return [200, headers, get_content(env, headers, asset, asset_key, asset.hash[:css][:css])]
|
151
98
|
end
|
152
99
|
end
|
153
100
|
|
154
101
|
return [404, {}, 'not found']
|
155
102
|
# hot reloading subscription
|
156
|
-
elsif Isomorfeus.development? && path_info == Isomorfeus.
|
103
|
+
elsif Isomorfeus.development? && path_info == Isomorfeus.hmr_websocket_path
|
157
104
|
if env['rack.upgrade?'] == :websocket
|
158
105
|
env['rack.upgrade'] = Isomorfeus::AssetManager::ServerSocketProcessor.new
|
159
106
|
end
|
@@ -166,11 +113,29 @@ module Isomorfeus
|
|
166
113
|
@app.call(env)
|
167
114
|
end
|
168
115
|
|
169
|
-
def
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
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
|
174
139
|
end
|
175
140
|
end
|
176
141
|
end
|
@@ -13,12 +13,12 @@ module Isomorfeus
|
|
13
13
|
@resolved_path ||= resolve_path
|
14
14
|
end
|
15
15
|
|
16
|
-
def to_s
|
17
|
-
"import(\"./#{@module_name}.rb.js\");\n"
|
16
|
+
def to_s(asset_name)
|
17
|
+
"import(\"./#{asset_name}/#{@module_name}.rb.js\");\n"
|
18
18
|
end
|
19
19
|
|
20
20
|
def to_dev_s(asset_name)
|
21
|
-
"import(\"#{Isomorfeus.assets_path}/#{asset_name}/#{@module_name}.rb.js\");\n"
|
21
|
+
"await import(\"#{Isomorfeus.assets_path}/#{asset_name}/#{@module_name}.rb.js\");\n"
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|