svelte-on-rails 19.2.4 → 20.0.0
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/svelte_on_rails/configuration.rb +59 -42
- data/lib/svelte_on_rails/installer/utils.rb +1 -1
- data/lib/svelte_on_rails/lib/fallback_renderer.rb +1 -0
- data/lib/svelte_on_rails/lib/view_helper_support.rb +2 -4
- data/lib/svelte_on_rails/railtie.rb +0 -8
- data/lib/svelte_on_rails/ssr_server.rb +96 -73
- data/lib/svelte_on_rails/view_helpers.rb +38 -46
- data/lib/tasks/svelte_on_rails_tasks.rake +47 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e61898f85783b55d7c82ac30d42e8aa73bcbdb1fa99a250691f82b712f81e975
|
|
4
|
+
data.tar.gz: b44558fa104458637bde419dc7a97ce68e6dee4e5b2814d1c41ed16210795af5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 493f5ab74088598e9b8a1d89e6e27ee32009545ec9d438040ee405a8d07fc791b77632f61377c18b71d4bee4a51fc599ad389a784198e0b370d398e437814174
|
|
7
|
+
data.tar.gz: 0e5ca1c8a2d9e60ccb1206871c10bba3ab2d42322b1f2e8982b7e06f988848bee518075b72ce1e2c5c7e4e2657c5716bf8505dc50cdbfb7a7fed516a5c4d923e
|
|
@@ -135,46 +135,7 @@ module SvelteOnRails
|
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
def node_bin_path
|
|
138
|
-
@node_bin_path ||=
|
|
139
|
-
n = ENV['SVELTE_ON_RAILS_NODE_BIN'] || 'node'
|
|
140
|
-
|
|
141
|
-
if n == 'node'
|
|
142
|
-
nvm_installed = false
|
|
143
|
-
nvm_dir = ENV['NVM_DIR'] || File.expand_path('~/.nvm')
|
|
144
|
-
nvm_installed ||= File.exist?("#{nvm_dir}/nvm.sh")
|
|
145
|
-
|
|
146
|
-
if nvm_installed
|
|
147
|
-
# Check for .nvmrc in the project root
|
|
148
|
-
project_root = rails_root || Dir.pwd
|
|
149
|
-
nvmrc_path = File.join(project_root, '.nvmrc')
|
|
150
|
-
use_nvmrc = File.exist?(nvmrc_path)
|
|
151
|
-
|
|
152
|
-
if use_nvmrc
|
|
153
|
-
# Read the version from .nvmrc
|
|
154
|
-
node_version = File.read(nvmrc_path).strip
|
|
155
|
-
# Ensure NVM is sourced and use the version from .nvmrc
|
|
156
|
-
command = "[ -s \"#{nvm_dir}/nvm.sh\" ] && . \"#{nvm_dir}/nvm.sh\" && nvm use #{node_version} > /dev/null 2>&1 && nvm which #{node_version}"
|
|
157
|
-
else
|
|
158
|
-
# Fallback to current NVM version
|
|
159
|
-
command = "[ -s \"#{nvm_dir}/nvm.sh\" ] && . \"#{nvm_dir}/nvm.sh\" && nvm which current"
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
node_path, status = Open3.capture2("bash -lc '#{command}'")
|
|
163
|
-
|
|
164
|
-
# Only update n if the command succeeded and output is non-empty
|
|
165
|
-
n = node_path.strip if status.success? && !node_path.strip.empty?
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
# Validate node_bin
|
|
170
|
-
unless n && !n.empty? && system("#{n} --version > /dev/null 2>&1")
|
|
171
|
-
raise "Node.js not found at '#{n || 'unknown'}'. Please configure SVELTE_ON_RAILS_NODE_BIN (e.g., to ~/.nvm/versions/node/vX.Y.Z/bin/node) or ensure 'node' is in the PATH. If using NVM, run `nvm alias default <version>` to set a default version or ensure a valid .nvmrc file is present."
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
n
|
|
175
|
-
rescue StandardError => e
|
|
176
|
-
raise "Failed to detect Node.js binary: «#{e.message}». Ensure Node.js is installed and accessible, or set SVELTE_ON_RAILS_NODE_BIN. If using .nvmrc, ensure the specified version is installed via NVM."
|
|
177
|
-
end
|
|
138
|
+
@node_bin_path ||= resolve_node_bin_path
|
|
178
139
|
end
|
|
179
140
|
|
|
180
141
|
def initialize_request_metrics(request_uuid)
|
|
@@ -187,6 +148,16 @@ module SvelteOnRails
|
|
|
187
148
|
|
|
188
149
|
end
|
|
189
150
|
|
|
151
|
+
def node_version_test
|
|
152
|
+
`#{node_bin_path} --version`.chomp
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def npm_package_version_test
|
|
156
|
+
JSON.parse(File.read(Rails.root.join('node_modules/@csedl/svelte-on-rails/package.json')))['version']
|
|
157
|
+
rescue
|
|
158
|
+
nil
|
|
159
|
+
end
|
|
160
|
+
|
|
190
161
|
private
|
|
191
162
|
|
|
192
163
|
def redis_cache_store_configs
|
|
@@ -305,12 +276,58 @@ module SvelteOnRails
|
|
|
305
276
|
raise "[Svelte-on-Rails] NPM-Package @csedl/svelte-on-rails: Could not detect version from: «#{sor}»"
|
|
306
277
|
end
|
|
307
278
|
|
|
308
|
-
if Gem::Version.new(version) < Gem::Version.new('
|
|
309
|
-
raise "[Svelte-on-Rails] NPM-Package @csedl/svelte-on-rails: At least version
|
|
279
|
+
if Gem::Version.new(version) < Gem::Version.new('14.0.0')
|
|
280
|
+
raise "[Svelte-on-Rails] NPM-Package @csedl/svelte-on-rails: At least version 14.0.0 is required, but found: «#{sor}»"
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
unless node_version_test.to_s.match(/v\d+\.\d+\.\d+/)
|
|
284
|
+
raise "[Svelte-on-Rails] Node Version could not be detected.\nPlease check your Node.js installation:\n#{@node_bin_path_log.join("\n")}"
|
|
310
285
|
end
|
|
311
286
|
end
|
|
312
287
|
|
|
313
288
|
end
|
|
314
289
|
|
|
290
|
+
def resolve_node_bin_path
|
|
291
|
+
@node_bin_path_log = []
|
|
292
|
+
|
|
293
|
+
if (ev = ENV['SVELTE_ON_RAILS_NODE_BIN']).present?
|
|
294
|
+
@node_bin_path_log << "environment variable SVELTE_ON_RAILS_NODE_BIN present"
|
|
295
|
+
return ev
|
|
296
|
+
end
|
|
297
|
+
@node_bin_path_log << "environment variable SVELTE_ON_RAILS_NODE_BIN not present"
|
|
298
|
+
|
|
299
|
+
nvm_dir = ENV['NVM_DIR'] || File.expand_path('~/.nvm')
|
|
300
|
+
unless File.exist?(File.join(nvm_dir, 'nvm.sh'))
|
|
301
|
+
@node_bin_path_log << "nvm not installed, fallback to «node»"
|
|
302
|
+
return 'node'
|
|
303
|
+
end
|
|
304
|
+
@node_bin_path_log << "nvm installed, found by #{ENV['NVM_DIR'] ? 'NVM_DIR' : '~/.nvm'}"
|
|
305
|
+
|
|
306
|
+
command = build_nvm_command(nvm_dir)
|
|
307
|
+
node_path, status = Open3.capture2('bash', '-lc', command)
|
|
308
|
+
|
|
309
|
+
if status.success? && !node_path.strip.empty?
|
|
310
|
+
@node_bin_path_log << "SUCCESS: bash -lc «#{command}»"
|
|
311
|
+
node_path.strip
|
|
312
|
+
else
|
|
313
|
+
@node_bin_path_log << "bash -lc «#{command}» FAILED, fallback to «node»"
|
|
314
|
+
'node'
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def build_nvm_command(nvm_dir)
|
|
319
|
+
nvmrc_path = File.join(rails_root || Dir.pwd, '.nvmrc')
|
|
320
|
+
nvm_sh = Shellwords.escape(File.join(nvm_dir, 'nvm.sh'))
|
|
321
|
+
|
|
322
|
+
if File.exist?(nvmrc_path)
|
|
323
|
+
@node_bin_path_log << "found .nvmrc in project root, checking version there"
|
|
324
|
+
version = Shellwords.escape(File.read(nvmrc_path).strip)
|
|
325
|
+
%([ -s #{nvm_sh} ] && . #{nvm_sh} && nvm use #{version} > /dev/null 2>&1 && nvm which #{version})
|
|
326
|
+
else
|
|
327
|
+
@node_bin_path_log << ".nvmrc not found in project root, using current NVM version"
|
|
328
|
+
%([ -s #{nvm_sh} ] && . #{nvm_sh} && nvm which current)
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
315
332
|
end
|
|
316
333
|
end
|
|
@@ -285,7 +285,7 @@ module SvelteOnRails
|
|
|
285
285
|
files.each do |f|
|
|
286
286
|
|
|
287
287
|
unless ssr_server_configured
|
|
288
|
-
next if File.basename(f) == File.basename(SvelteOnRails::SsrServer.
|
|
288
|
+
next if File.basename(f) == File.basename(SvelteOnRails::SsrServer.ssr_server_bin_path)
|
|
289
289
|
end
|
|
290
290
|
|
|
291
291
|
paths.push(
|
|
@@ -154,7 +154,8 @@ module SvelteOnRails
|
|
|
154
154
|
def log_completed(message)
|
|
155
155
|
ms = ((Time.now - @start_time) * 1000)
|
|
156
156
|
@conf.request_metrics[:total_time] += ms
|
|
157
|
-
|
|
157
|
+
msg = " [SOR] #{component_paths[:name]}.svelte #{message} (#{ms.round(1)}ms)"
|
|
158
|
+
Rails.logger.info msg
|
|
158
159
|
end
|
|
159
160
|
|
|
160
161
|
def render_svelte(current_template)
|
|
@@ -191,10 +192,8 @@ module SvelteOnRails
|
|
|
191
192
|
# render
|
|
192
193
|
|
|
193
194
|
res = if @cached_content
|
|
194
|
-
msg = "returned from cache#{", with uncached props" if @cached_props.key?(:_uncached)}"
|
|
195
195
|
@cached_content.html_safe
|
|
196
196
|
else
|
|
197
|
-
msg = "Rendered"
|
|
198
197
|
@skip_caching = false
|
|
199
198
|
@conf.debug_log(debug?, component_paths[:name], "rendered and stored to cache (key: «#{cache_key}»)") do
|
|
200
199
|
r = view_context.instance_eval(&block)
|
|
@@ -204,7 +203,6 @@ module SvelteOnRails
|
|
|
204
203
|
r
|
|
205
204
|
end
|
|
206
205
|
end
|
|
207
|
-
log_completed(msg)
|
|
208
206
|
res
|
|
209
207
|
|
|
210
208
|
end
|
|
@@ -20,14 +20,6 @@ module SvelteOnRails
|
|
|
20
20
|
|
|
21
21
|
ActiveRecord::Base.extend SvelteOnRails::ActiveRecordOptIn
|
|
22
22
|
|
|
23
|
-
# # Include instance-level extensions for ActiveRecord instances (e.g., @article)
|
|
24
|
-
# include SvelteOnRails::ActiveRecordExtensions
|
|
25
|
-
#
|
|
26
|
-
# # Extend ActiveRecord::Base with class-level extensions (e.g., Article)
|
|
27
|
-
# ActiveRecord::Base.extend SvelteOnRails::ActiveRecordClassExtensions
|
|
28
|
-
|
|
29
|
-
# This also extends ActiveRecord::Relation (e.g., @articles)
|
|
30
|
-
#ActiveRecord::Relation.include SvelteOnRails::ActiveRecordRelationExtensions
|
|
31
23
|
end
|
|
32
24
|
end
|
|
33
25
|
|
|
@@ -1,84 +1,48 @@
|
|
|
1
1
|
require 'singleton'
|
|
2
2
|
|
|
3
3
|
module SvelteOnRails
|
|
4
|
+
|
|
4
5
|
class SsrServer
|
|
5
6
|
|
|
6
7
|
include Singleton
|
|
7
8
|
|
|
8
|
-
attr_reader :
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
elsif Rails.env.development?
|
|
16
|
-
50
|
|
17
|
-
elsif Rails.env.production?
|
|
18
|
-
1000
|
|
19
|
-
else
|
|
20
|
-
100
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def logfile_path
|
|
25
|
-
Rails.root.join("log/svelte-ssr-server-#{Rails.env}.log")
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def socket_path
|
|
29
|
-
@socket_path ||= begin
|
|
30
|
-
|
|
31
|
-
app_sock = Rails.root.join("tmp/sockets/#{@socket_namespace}-#{Process.pid}.sock").to_s
|
|
32
|
-
preferred_dir = File.dirname(app_sock)
|
|
33
|
-
FileUtils.mkdir_p(preferred_dir)
|
|
34
|
-
|
|
35
|
-
if app_sock.to_s.length < 104
|
|
36
|
-
app_sock
|
|
37
|
-
else
|
|
38
|
-
FileUtils.rm_f(app_sock) if File.exist?(app_sock)
|
|
39
|
-
# Fallback to shorter path in /tmp
|
|
40
|
-
dir = File.expand_path("/tmp/svelte")
|
|
41
|
-
FileUtils.mkdir_p(dir)
|
|
42
|
-
FileUtils.chmod(0777, dir)
|
|
43
|
-
s = dir + "/#{@socket_namespace}-#{Process.pid}.sock"
|
|
44
|
-
start_server_log(nil, "sockets longer than 104 chars are risky, fallback to: #{s}")
|
|
45
|
-
s
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def self.script_path_full
|
|
52
|
-
Rails.root.join(script_path)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def self.script_path
|
|
56
|
-
Pathname('node_modules/@csedl/svelte-on-rails/bin/svelte-ssr-server.js')
|
|
57
|
-
end
|
|
9
|
+
attr_reader :socket_namespace,
|
|
10
|
+
:logfile_path,
|
|
11
|
+
:logfile_max_lines,
|
|
12
|
+
:socket_path,
|
|
13
|
+
:ssr_server_bin_path,
|
|
14
|
+
:node_bin,
|
|
15
|
+
:ssr_server_ppid_file
|
|
58
16
|
|
|
59
17
|
# methods
|
|
60
18
|
|
|
61
|
-
def self.instance
|
|
62
|
-
@instance ||= new
|
|
19
|
+
def self.instance(dry_run_ppid: nil)
|
|
20
|
+
@instance ||= new(dry_run_ppid: dry_run_ppid)
|
|
63
21
|
end
|
|
64
22
|
|
|
65
|
-
def initialize
|
|
23
|
+
def initialize(dry_run_ppid: nil)
|
|
66
24
|
|
|
67
25
|
@socket_namespace = [
|
|
68
26
|
"svelte-ssr",
|
|
69
27
|
Rails.application.class.module_parent_name[0..30],
|
|
70
28
|
Rails.env,
|
|
71
29
|
].join("-")
|
|
30
|
+
@dry_run_ppid = dry_run_ppid if dry_run_ppid
|
|
72
31
|
|
|
73
|
-
@
|
|
32
|
+
@logfile_path = Rails.root.join("log/svelte-ssr-server-#{Rails.env}.log")
|
|
33
|
+
@logfile_max_lines = build_logfile_max_lines
|
|
34
|
+
@socket_path = build_socket_path
|
|
35
|
+
@use_ssr_server = SvelteOnRails::Configuration.instance.configs[:use_ssr_server]
|
|
36
|
+
@node_bin = SvelteOnRails::Configuration.instance.node_bin_path
|
|
37
|
+
@ssr_server_bin_path = Rails.root.join(Pathname('node_modules/@csedl/svelte-on-rails/bin/svelte-ssr-server.js'))
|
|
38
|
+
@ssr_server_ppid_file = Rails.root.join("tmp", "pids", 'svelte_on_rails.ppid')
|
|
74
39
|
|
|
75
|
-
@
|
|
76
|
-
if @config.configs[:use_ssr_server] && defined?(Rails::Server)
|
|
40
|
+
if @use_ssr_server && defined?(Rails::Server)
|
|
77
41
|
|
|
78
42
|
start_node_server!
|
|
79
43
|
|
|
80
44
|
at_exit do
|
|
81
|
-
|
|
45
|
+
kill_my_server
|
|
82
46
|
end
|
|
83
47
|
end
|
|
84
48
|
|
|
@@ -87,7 +51,7 @@ module SvelteOnRails
|
|
|
87
51
|
def render(component, props, debug, view_path_proc)
|
|
88
52
|
|
|
89
53
|
# fetch asset
|
|
90
|
-
manifest =
|
|
54
|
+
manifest = SvelteOnRails::Configuration.instance.manifest(debug, component[:name])
|
|
91
55
|
_asset_path = manifest[component[:path]]['file']
|
|
92
56
|
full_asset_path = Rails.root.join('public', 'svelte-ssr', _asset_path)
|
|
93
57
|
|
|
@@ -119,6 +83,7 @@ module SvelteOnRails
|
|
|
119
83
|
else
|
|
120
84
|
raise e
|
|
121
85
|
end
|
|
86
|
+
restart_my_server
|
|
122
87
|
end
|
|
123
88
|
|
|
124
89
|
shorten_logfile
|
|
@@ -150,7 +115,7 @@ module SvelteOnRails
|
|
|
150
115
|
:render_failed,
|
|
151
116
|
"Render #{component[:file_basename]}.svelte",
|
|
152
117
|
[
|
|
153
|
-
raw_response['
|
|
118
|
+
raw_response['logs'].to_a.join("\n"),
|
|
154
119
|
"View:\n#{view_path_proc.call}\nComponent:\n#{Rails.root.join(component[:path]).to_s}#{imps}",
|
|
155
120
|
]
|
|
156
121
|
)
|
|
@@ -172,7 +137,7 @@ module SvelteOnRails
|
|
|
172
137
|
end
|
|
173
138
|
|
|
174
139
|
def configured?
|
|
175
|
-
@configured ||= File.exist?(
|
|
140
|
+
@configured ||= File.exist?(@ssr_server_bin_path)
|
|
176
141
|
end
|
|
177
142
|
|
|
178
143
|
def ping?
|
|
@@ -184,7 +149,7 @@ module SvelteOnRails
|
|
|
184
149
|
response = ''
|
|
185
150
|
begin
|
|
186
151
|
sock = UNIXSocket.new(socket_path)
|
|
187
|
-
request = "GET /
|
|
152
|
+
request = "GET /health HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"
|
|
188
153
|
sock.write(request)
|
|
189
154
|
response = sock.read
|
|
190
155
|
sock.close
|
|
@@ -192,18 +157,28 @@ module SvelteOnRails
|
|
|
192
157
|
puts "[SOR] Ping Failed: #{e.message}"
|
|
193
158
|
end
|
|
194
159
|
if response.match?(/^HTTP\/\d\.\d 200/)
|
|
195
|
-
|
|
160
|
+
r = parse_body_json(response)
|
|
161
|
+
unless r['version'].split('.').first.to_i >= 14
|
|
162
|
+
puts "[SOR] WARNING: Required SSR Server version is at least 14.x, you have installed @csedl/svelte-on-rails: #{r['version']}"
|
|
163
|
+
end
|
|
164
|
+
@alive = r['status'] == 'alive'
|
|
196
165
|
end
|
|
197
166
|
end
|
|
198
167
|
|
|
199
|
-
def start_node_server!
|
|
168
|
+
def start_node_server!(started_by = "rails-boot-#{Rails.env}-#{Process.ppid}")
|
|
169
|
+
|
|
170
|
+
# notice ppid
|
|
171
|
+
unless @dry_run_ppid
|
|
172
|
+
FileUtils.mkdir_p(@ssr_server_ppid_file.dirname)
|
|
173
|
+
File.write(@ssr_server_ppid_file, Process.ppid.to_s)
|
|
174
|
+
end
|
|
200
175
|
|
|
201
|
-
cnf = SvelteOnRails::Configuration.instance
|
|
202
176
|
start = Time.now
|
|
203
177
|
cmd = [
|
|
204
|
-
"
|
|
205
|
-
|
|
206
|
-
|
|
178
|
+
"SVELTE_SSR_SERVER_STARTED_BY=r#{started_by}",
|
|
179
|
+
@node_bin,
|
|
180
|
+
@ssr_server_bin_path,
|
|
181
|
+
@socket_path
|
|
207
182
|
].join(' ')
|
|
208
183
|
|
|
209
184
|
@node_server_output = {}
|
|
@@ -218,6 +193,7 @@ module SvelteOnRails
|
|
|
218
193
|
status: status
|
|
219
194
|
}
|
|
220
195
|
end
|
|
196
|
+
start_server_log(start, "Node Version: #{Configuration.instance.node_version_test}, package version: #{Configuration.instance.npm_package_version_test}")
|
|
221
197
|
start_server_log(start, "Start running Svelte-SSR-Server...")
|
|
222
198
|
|
|
223
199
|
until node_server_pid do
|
|
@@ -225,11 +201,10 @@ module SvelteOnRails
|
|
|
225
201
|
start_server_log(start, "Waiting for node server process-id")
|
|
226
202
|
start_server_timeout!(start)
|
|
227
203
|
end
|
|
228
|
-
start_server_log(start, "Node-server process-id: #{node_server_pid}")
|
|
229
204
|
|
|
230
205
|
until File.exist?(socket_path) do
|
|
231
|
-
sleep 0.
|
|
232
|
-
start_server_log(start, "Waiting for socket to be created
|
|
206
|
+
sleep 0.1
|
|
207
|
+
start_server_log(start, "Waiting for socket to be created")
|
|
233
208
|
start_server_timeout!(start)
|
|
234
209
|
end
|
|
235
210
|
start_server_log(start, "Socket created: #{socket_path}")
|
|
@@ -251,7 +226,7 @@ module SvelteOnRails
|
|
|
251
226
|
|
|
252
227
|
leftover = stdout.split("\n").map do |line|
|
|
253
228
|
if line.match?(/\/#{@socket_namespace}-[0-9]+.sock$/)
|
|
254
|
-
unless line.
|
|
229
|
+
unless line.match?(/\/#{@socket_namespace}-#{Process.ppid}.sock$/)
|
|
255
230
|
line.match(/[0-9]+/).to_s.to_i
|
|
256
231
|
end
|
|
257
232
|
end
|
|
@@ -264,6 +239,25 @@ module SvelteOnRails
|
|
|
264
239
|
start_server_log(nil, "Killed #{leftover.length} leftover processes") if leftover.length >= 1
|
|
265
240
|
end
|
|
266
241
|
|
|
242
|
+
def kill_my_server
|
|
243
|
+
Process.kill("SIGINT", (node_server_pid || 0)) if node_server_pid
|
|
244
|
+
File.delete(@ssr_server_ppid_file)
|
|
245
|
+
rescue
|
|
246
|
+
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def restart_my_server
|
|
250
|
+
return unless @server_restarted_time > 1.minutes.ago
|
|
251
|
+
@server_restarted_count ||= 1
|
|
252
|
+
kill_my_server
|
|
253
|
+
begin
|
|
254
|
+
start_node_server!("Restart-after-failure-#{@server_restarted_count}")
|
|
255
|
+
@server_restarted_time = Time.now
|
|
256
|
+
@server_restarted_count += 1
|
|
257
|
+
rescue
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
267
261
|
def alive?
|
|
268
262
|
@alive
|
|
269
263
|
end
|
|
@@ -273,7 +267,7 @@ module SvelteOnRails
|
|
|
273
267
|
"ps aux | grep svelte"
|
|
274
268
|
)
|
|
275
269
|
stdout.split("\n").each do |line|
|
|
276
|
-
if line.include?("#{@socket_namespace}-#{Process.
|
|
270
|
+
if line.include?("#{@socket_namespace}-#{Process.ppid}.sock")
|
|
277
271
|
return line.match(/[0-9]+/).to_s.to_i
|
|
278
272
|
end
|
|
279
273
|
end
|
|
@@ -294,7 +288,7 @@ module SvelteOnRails
|
|
|
294
288
|
def start_server_timeout!(start_time, timeout: 2000)
|
|
295
289
|
ms = ((Time.now - start_time) * 1000).round(1)
|
|
296
290
|
if ms > timeout
|
|
297
|
-
|
|
291
|
+
SvelteOnRails::Lib::Utils.error_log(
|
|
298
292
|
:ssr_server_unreachable,
|
|
299
293
|
'SSR Server could not be started. ',
|
|
300
294
|
[
|
|
@@ -346,7 +340,36 @@ module SvelteOnRails
|
|
|
346
340
|
end
|
|
347
341
|
end
|
|
348
342
|
|
|
343
|
+
def build_logfile_max_lines
|
|
344
|
+
if Rails.env.test?
|
|
345
|
+
20
|
|
346
|
+
elsif Rails.env.development?
|
|
347
|
+
50
|
|
348
|
+
elsif Rails.env.production?
|
|
349
|
+
1000
|
|
350
|
+
else
|
|
351
|
+
100
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def build_socket_path
|
|
356
|
+
app_sock = Rails.root.join("tmp/sockets/#{@socket_namespace}-#{@dry_run_ppid || Process.ppid}.sock").to_s
|
|
357
|
+
FileUtils.mkdir_p(File.dirname(app_sock))
|
|
358
|
+
|
|
359
|
+
return app_sock if app_sock.length < 104
|
|
360
|
+
|
|
361
|
+
# Fallback: socket paths > 104 chars are unreliable on macOS/BSD
|
|
362
|
+
FileUtils.rm_f(app_sock) if File.exist?(app_sock)
|
|
363
|
+
dir = File.expand_path("/tmp/svelte")
|
|
364
|
+
FileUtils.mkdir_p(dir)
|
|
365
|
+
FileUtils.chmod(0777, dir)
|
|
366
|
+
fallback = "#{dir}/#{@socket_namespace}-#{@dry_run_ppid || Process.ppid}.sock"
|
|
367
|
+
start_server_log(nil, "sockets longer than 104 chars are risky, fallback to: #{fallback}")
|
|
368
|
+
fallback
|
|
369
|
+
end
|
|
370
|
+
|
|
349
371
|
end
|
|
350
372
|
|
|
351
373
|
class SsrError < StandardError; end
|
|
374
|
+
|
|
352
375
|
end
|
|
@@ -32,19 +32,22 @@ module SvelteOnRails
|
|
|
32
32
|
if support.ssr?
|
|
33
33
|
if config.watch_changes? && !config.build_status['passed']
|
|
34
34
|
sor_error_tag(support, wrapper_html, component_props, 'server-side-svelte-build-error', 'SVELTE BUILD FAILED')
|
|
35
|
+
|
|
35
36
|
elsif caching
|
|
36
37
|
support.set_request_metrics(:from_cache)
|
|
37
38
|
if component_props.key?(:_uncached)
|
|
38
39
|
|
|
40
|
+
# With Caching:
|
|
39
41
|
# when we have uncached props, we do not cache the wrapper tag
|
|
40
42
|
|
|
41
43
|
attr = support.tag_attributes(wrapper_html, component_props)
|
|
42
|
-
content_tag(:div, attr) do
|
|
44
|
+
r = content_tag(:div, attr) do
|
|
43
45
|
support.render_cached(self) do
|
|
44
|
-
|
|
45
|
-
if
|
|
46
|
-
concat(
|
|
47
|
-
concat(
|
|
46
|
+
rnd = support.render_svelte(@current_template)
|
|
47
|
+
if rnd[:success]
|
|
48
|
+
concat(rnd[:head].html_safe)
|
|
49
|
+
concat(rnd[:html].html_safe)
|
|
50
|
+
support.log_completed("returned from cache, with uncached props#{', (Fallback!)' if rnd[:fallback]}")
|
|
48
51
|
else
|
|
49
52
|
sor_error_tag(support, wrapper_html, component_props, 'server-side-svelte-render-error', 'SVELTE RENDER FAILED')
|
|
50
53
|
end
|
|
@@ -53,26 +56,47 @@ module SvelteOnRails
|
|
|
53
56
|
|
|
54
57
|
else
|
|
55
58
|
|
|
59
|
+
# With Caching:
|
|
56
60
|
# when all props are cached, we can cache the wrapper tag too
|
|
57
61
|
# ... but using only cached props for making sure we don't cache any dynamic content
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
log = 'returned from cache'
|
|
64
|
+
res = support.render_cached(self) do
|
|
65
|
+
rnd = support.render_svelte(@current_template)
|
|
66
|
+
if rnd[:success]
|
|
62
67
|
attr = support.tag_attributes(wrapper_html, support.cached_props)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
concat(
|
|
68
|
+
log = "rendered#{' (Fallback!) and stored to cache' if rnd[:fallback]}"
|
|
69
|
+
r = content_tag(:div, attr) do
|
|
70
|
+
concat(rnd[:head].html_safe)
|
|
71
|
+
concat(rnd[:html].html_safe)
|
|
66
72
|
end
|
|
73
|
+
|
|
74
|
+
r
|
|
67
75
|
else
|
|
76
|
+
log = "ERROR"
|
|
68
77
|
sor_error_tag(support, wrapper_html, component_props, 'server-side-svelte-render-error', 'SVELTE RENDER FAILED')
|
|
69
78
|
end
|
|
70
79
|
end
|
|
71
|
-
|
|
80
|
+
support.log_completed(log)
|
|
81
|
+
res
|
|
72
82
|
end
|
|
73
83
|
else
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
|
|
85
|
+
# Without caching:
|
|
86
|
+
# just render
|
|
87
|
+
|
|
88
|
+
rnd = support.render_svelte(@current_template)
|
|
89
|
+
r = if rnd[:success]
|
|
90
|
+
attr = support.tag_attributes(wrapper_html, component_props)
|
|
91
|
+
content_tag(:div, attr) do
|
|
92
|
+
concat(rnd[:head].html_safe)
|
|
93
|
+
concat(rnd[:html].html_safe)
|
|
94
|
+
end
|
|
95
|
+
else
|
|
96
|
+
sor_error_tag(support, wrapper_html, component_props, 'server-side-svelte-render-error', 'SVELTE RENDER FAILED')
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
support.log_completed("Rendered#{rnd[:fallback] ? ' (Fallback!)' : ''} #{'as empty element that will be mounted on the client side' unless support.ssr?}")
|
|
76
100
|
r
|
|
77
101
|
end
|
|
78
102
|
|
|
@@ -83,38 +107,6 @@ module SvelteOnRails
|
|
|
83
107
|
|
|
84
108
|
private
|
|
85
109
|
|
|
86
|
-
def render_component(support, html_options, component_props)
|
|
87
|
-
|
|
88
|
-
caller_loc = Proc.new do
|
|
89
|
-
v_path = @current_template.identifier
|
|
90
|
-
caller_locations.find { |loc| loc.to_s.include?(v_path) }.to_s.match(/^[\s\S]+(:[0-9]+(?=:in))/).to_s
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
ssr_result = if SvelteOnRails::SsrServer.instance.alive?
|
|
94
|
-
SvelteOnRails::SsrServer.instance.render(
|
|
95
|
-
support.component_paths,
|
|
96
|
-
support.cached_props,
|
|
97
|
-
support.debug?,
|
|
98
|
-
caller_loc
|
|
99
|
-
)
|
|
100
|
-
else
|
|
101
|
-
SvelteOnRails::Lib::FallbackRenderer.render(support.component_paths, support.cached_props, support.debug?)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
if ssr_result[:success]
|
|
105
|
-
support.set_request_metrics(:rendered)
|
|
106
|
-
attr = support.tag_attributes(html_options, component_props)
|
|
107
|
-
content_tag(:div, attr) do
|
|
108
|
-
concat(ssr_result[:head].html_safe)
|
|
109
|
-
concat(ssr_result[:html].html_safe)
|
|
110
|
-
end
|
|
111
|
-
else
|
|
112
|
-
support.instance_variable_set(:@skip_caching, true)
|
|
113
|
-
sor_error_tag(support, html_options, component_props, 'server-side-svelte-render-error', 'SVELTE RENDER FAILED')
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
end
|
|
117
|
-
|
|
118
110
|
def render_empty_tag(support, html_options, component_props)
|
|
119
111
|
|
|
120
112
|
support.set_request_metrics(:empty)
|
|
@@ -3,7 +3,53 @@ namespace :svelte_on_rails do
|
|
|
3
3
|
task :precompile do
|
|
4
4
|
SvelteOnRails::Configuration.instance.vite_build
|
|
5
5
|
end
|
|
6
|
-
end
|
|
7
6
|
|
|
7
|
+
desc "check ssr requirements and status"
|
|
8
|
+
task :check do
|
|
9
|
+
|
|
10
|
+
configs = SvelteOnRails::Configuration.instance
|
|
11
|
+
ppid_file = Rails.root.join("tmp", "pids", 'svelte_on_rails.ppid')
|
|
12
|
+
ppid = (ppid_file.exist? ? File.read(ppid_file).chomp : nil)
|
|
13
|
+
server = SvelteOnRails::SsrServer.instance(dry_run_ppid: ppid)
|
|
14
|
+
socket_path = server.socket_path
|
|
15
|
+
|
|
16
|
+
puts '=' * 80
|
|
17
|
+
puts "Svelte on Rails SSR Server"
|
|
18
|
+
puts '=' * 80
|
|
19
|
+
puts
|
|
20
|
+
puts 'Node'
|
|
21
|
+
puts label('Node bin') + server.node_bin
|
|
22
|
+
puts label('Node version') + configs.node_version_test
|
|
23
|
+
puts label('SSR Server bin') + server.ssr_server_bin_path.to_s
|
|
24
|
+
puts label('SSR Server version') + configs.npm_package_version_test.to_s
|
|
25
|
+
puts
|
|
26
|
+
puts 'Rails instance'
|
|
27
|
+
if !server.ssr_server_ppid_file.exist?
|
|
28
|
+
puts label('Process.ppid') + "#{server.ssr_server_ppid_file} not found, rails seems not to run"
|
|
29
|
+
else
|
|
30
|
+
puts label('Process.ppid') + ppid
|
|
31
|
+
puts label('Socket') + socket_path
|
|
32
|
+
puts label('Server uptime')
|
|
33
|
+
end
|
|
34
|
+
puts
|
|
35
|
+
puts '=' * 80
|
|
36
|
+
puts 'MORE DETAILS:'
|
|
37
|
+
puts
|
|
38
|
+
puts 'How was the node bin path determined:'
|
|
39
|
+
configs.instance_variable_get(:@node_bin_path_log).each do |line|
|
|
40
|
+
puts " • #{line}"
|
|
41
|
+
end
|
|
42
|
+
puts
|
|
43
|
+
puts 'Command for check the server instance:'
|
|
44
|
+
puts " • curl --unix-socket #{socket_path} http://localhost"
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def label(msg)
|
|
49
|
+
l = msg.length
|
|
50
|
+
" #{msg}:"[0..20] + (msg.length > 22 ? ':' : '') + ' ' * (20 - l)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
8
54
|
|
|
9
55
|
Rake::Task["assets:precompile"].enhance ["svelte_on_rails:precompile"]
|