isomorfeus-asset-manager 0.14.12 → 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 +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
|