svelte-on-rails 22.2.0 → 22.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a32126c57f42015b2fae36849a77266d174dfc6234a5958c924b490e4c1efc47
4
- data.tar.gz: b264887e056b7d3aeb763923d1f20eccdab81000bc1c7dae63b7c909397157c0
3
+ metadata.gz: e4e1180e9510fa0b8592b0b17be5ae1f75348124861184022648f2ec6b96865d
4
+ data.tar.gz: 737ff843db6d9fe9ae04d34fd24b214089368d2b34357ac0e64a14ff90c13d52
5
5
  SHA512:
6
- metadata.gz: ec6ad182cd5a2f06c654017f2ddbc81fe07b07498339262b0ec145d7fbaa815d12abef5a681930080d8edaee57e536f036399e5df011c8e3d3413ecea9b0a5f7
7
- data.tar.gz: e67beb89b3a4ed77bdb3d7cc39f54596769c1b9cd25d12b7db7341cf860176d0b9a633b6fba4e4703a2a48d42509a1b18a977345b0a91214cefe556c760766b2
6
+ metadata.gz: 769b3c284cdddd35fb86895a29a6ae3a7bce52f501cb689856c1d166892fd360a264eafe274f2cc41944ec57d1a044d25c2c3a1934149ce9e0d1afb972f4501a
7
+ data.tar.gz: 2d067a4983fb063fc1e38a1a68e235050d405dad829bea0727ceed9a6d0a35752909d2ae2aba99177e73af21ef01e0cd848d51c30612838ea48fda5163c95c90
@@ -18,6 +18,7 @@ require "svelte_on_rails/lib/to_svelte_values"
18
18
  require "svelte_on_rails/lib/to_svelte_support"
19
19
  require "svelte_on_rails/lib/to_svelte_translations"
20
20
  require "svelte_on_rails/lib/cache_warmer"
21
+ require "svelte_on_rails/lib/boot_context"
21
22
 
22
23
  # installer
23
24
  require 'svelte_on_rails/installer/utils'
@@ -44,14 +44,9 @@ module SvelteOnRails
44
44
 
45
45
  if @configs[:redis_cache_store]
46
46
  store = @configs[:redis_cache_store]
47
- if store['expires_in'].is_a?(String)
48
- @configs[:redis_cache_store]['expires_in'] = parse_duration(
49
- store['expires_in']
50
- )
51
- end
52
47
  @redis_namespace = store[:namespace]
53
48
  end
54
- @redis_namespace ||= "svelte-on-rails:#{Rails.env rescue 'no-env'}"
49
+ @redis_namespace ||= "#{app_name}:svelte-on-rails:#{Rails.env rescue 'no-env'}"
55
50
  @configs[:skip_ssr_header] ||= 'X-Turbo-Request-ID'
56
51
  if defined? Redis
57
52
  @redis_instance = Redis.new(url: redis_cache_store[:url])
@@ -60,6 +55,7 @@ module SvelteOnRails
60
55
  validate_serialized_configs
61
56
  custom_config_validations
62
57
  validate_npm_packages
58
+ process_configs
63
59
  end
64
60
 
65
61
  def set_config_defaults
@@ -175,11 +171,18 @@ module SvelteOnRails
175
171
  nil
176
172
  end
177
173
 
174
+ def process_configs
175
+ ex = @configs[:cache_expires_in]
176
+ if ex
177
+ @configs[:cache_expires_in] = ex.split('.').first.to_i.send(ex.split('.').last)
178
+ end
179
+ end
180
+
178
181
  private
179
182
 
180
183
  def redis_cache_store_configs
181
184
  if defined?(Rails.application) && Rails.application.config.cache_store.is_a?(Array) && Rails.application.config.cache_store.first == :redis_cache_store
182
- { redis_cache_store: Rails.application.config.cache_store.second.stringify_keys }
185
+ { redis_cache_store: Rails.application.config.cache_store.second.deep_symbolize_keys }
183
186
  else
184
187
  {}
185
188
  end
@@ -228,7 +231,7 @@ module SvelteOnRails
228
231
  ssr: { options_required: [:auto, true, false] },
229
232
  watch_changes: { options_optional: [true, false] },
230
233
 
231
- redis_cache_store: { hash_of_strings_optional: [:url, :namespace, :expires_in] },
234
+ redis_cache_store: { hash_of_strings_optional: [:url, :namespace] },
232
235
  turbo_stream: { hash_of_strings_optional: [:target_html_id, :channel] },
233
236
  action_cable: { hash_of_strings_optional: [:channel] },
234
237
 
@@ -245,6 +248,11 @@ module SvelteOnRails
245
248
  elsif k == :default_components_root
246
249
  available_keys = ['components_subdir'] + @configs[:extra_component_paths].to_a
247
250
  raise "[SOR] Invalid configuration: #{k} must be one of: [«#{available_keys.join('», «')}»]" unless available_keys.include?(v)
251
+ elsif k == :cache_expires_in
252
+ reg = /^[0-9]+\.(minutes|hours|days)$/
253
+ unless v.match(reg)
254
+ raise "#{k} must match #{reg}"
255
+ end
248
256
  elsif validation[:required]
249
257
  if validation[:required] == :string
250
258
  raise "[SOR] Missing configuration: #{k} must contain a string" if !v.present? || !v.is_a?(String)
@@ -262,6 +270,8 @@ module SvelteOnRails
262
270
  raise "[SOR] Invalid configuration: #{k} must be one of #{validation[:options_optional]}" unless validation[:options_optional].include?(v)
263
271
  elsif validation[:hash_of_strings_optional]
264
272
 
273
+ raise "[SOR] #{k} is empty. Either remove this key or provide a hash" unless v.present?
274
+
265
275
  _available_keys = validation[:hash_of_strings_optional]
266
276
  v.each do |_k, _v|
267
277
  raise "[SOR] Invalid configuration: #{k}/#{_k} («#{_v}» / #{_v.class}) must be a string" unless _v.is_a?(String)
@@ -367,5 +377,12 @@ module SvelteOnRails
367
377
  end
368
378
  end
369
379
 
380
+ def app_name
381
+ # Same logic Rails uses internally for e.g. cache_store default namespace
382
+ Rails.application.class&.module_parent_name.to_s[0..30].underscore.presence || 'app'
383
+ rescue StandardError
384
+ 'app'
385
+ end
386
+
370
387
  end
371
388
  end
@@ -0,0 +1,98 @@
1
+ module SvelteOnRails
2
+ module BootContext
3
+ module_function
4
+
5
+ # We deliberately use a BLACKLIST + program-name check, not a whitelist of
6
+ # loaded constants. Reason: `puma` is typically in the app's Gemfile default
7
+ # group, so `defined?(::Puma::Launcher)` is truthy even inside `rails console`
8
+ # or `rails assets:precompile`.
9
+ def serving_http?
10
+ # Explicit overrides for tests / edge cases:
11
+ return true if ENV["SVELTE_ON_RAILS_FORCE_SSR"] == "1"
12
+ return false if ENV["SVELTE_ON_RAILS_DISABLE_SSR"] == "1"
13
+
14
+ return false if rake_task?
15
+ return false if rails_console?
16
+ return false if rails_runner?
17
+ return false if rails_dbconsole?
18
+ return false if rails_generator?
19
+ return false if test_runner?
20
+
21
+ # Positive signal: `rails server` sets this constant during command dispatch.
22
+ return true if defined?(Rails::Server)
23
+
24
+ # Positive signal: launched directly via a server binary (bundle exec puma,
25
+ # rackup, unicorn, falcon, passenger). $PROGRAM_NAME is set by the launcher
26
+ # before it requires the app, so this is reliable.
27
+ return true if server_program_name?
28
+
29
+ # Default: assume this is NOT an HTTP-serving context. Better to be silent
30
+ # than to spawn an unwanted Node process; users can force with the ENV var.
31
+ false
32
+ end
33
+
34
+ def description
35
+ return "rake tasks: #{Rake.application.top_level_tasks.join(', ')}" if rake_task?
36
+ return "rails console" if rails_console?
37
+ return "rails runner" if rails_runner?
38
+ return "rails dbconsole" if rails_dbconsole?
39
+ return "rails generator" if rails_generator?
40
+ return "test runner (#{test_runner_name})" if test_runner?
41
+ return "rails server" if defined?(Rails::Server)
42
+ "program=#{File.basename($PROGRAM_NAME)}"
43
+ end
44
+
45
+ # --- detectors -----------------------------------------------------------
46
+
47
+ def rake_task?
48
+ defined?(Rake) && Rake.respond_to?(:application) && Rake.application.top_level_tasks.any?
49
+ end
50
+
51
+ def rails_console?
52
+ defined?(Rails::Console) ||
53
+ program_basename == "irb" ||
54
+ (defined?(IRB) && $PROGRAM_NAME.to_s.include?("irb"))
55
+ end
56
+
57
+ def rails_runner?
58
+ defined?(Rails::Command::RunnerCommand) &&
59
+ Rails::Command.const_defined?(:RunnerCommand) &&
60
+ current_rails_command?("runner")
61
+ end
62
+
63
+ def rails_dbconsole?
64
+ defined?(Rails::DBConsole) || current_rails_command?("dbconsole")
65
+ end
66
+
67
+ def rails_generator?
68
+ defined?(Rails::Generators) && current_rails_command?("generate", "destroy", "new")
69
+ end
70
+
71
+ def test_runner?
72
+ !test_runner_name.nil?
73
+ end
74
+
75
+ def test_runner_name
76
+ return "rspec" if $PROGRAM_NAME.to_s.include?("rspec")
77
+ return "minitest" if defined?(Minitest) && Minitest.respond_to?(:run) && !defined?(Rails::Server)
78
+ return "cucumber" if $PROGRAM_NAME.to_s.include?("cucumber")
79
+ nil
80
+ end
81
+
82
+ def server_program_name?
83
+ %w[puma rackup unicorn unicorn_rails falcon passenger].include?(program_basename)
84
+ end
85
+
86
+ def program_basename
87
+ File.basename($PROGRAM_NAME.to_s)
88
+ end
89
+
90
+ # `rails <command>` sets ARGV[0] to the command name before Rails::Command
91
+ # dispatches. This is stable across Rails 6/7/8.
92
+ def current_rails_command?(*names)
93
+ argv0 = (defined?(ARGV) && ARGV.first) || nil
94
+ return false unless argv0
95
+ names.include?(argv0.to_s)
96
+ end
97
+ end
98
+ end
@@ -5,7 +5,14 @@ module SvelteOnRails
5
5
  class ViewHelperSupport
6
6
 
7
7
  UNCACHED_PROPS_PLACEHOLDER = "**Uncached Props are available only after hydration**"
8
- RENDER_OPTIONS = { ssr: [true, false, :auto], hydrate: :bool, debug: :bool, cache_key: :string_array, expires_in: :integer, cached: :bool }
8
+ RENDER_OPTIONS = {
9
+ ssr: [:oneof, [true, false, :auto]],
10
+ hydrate: [:oneof, [true, false]],
11
+ debug: [:oneof, [true, false]],
12
+ cache_key: [:typeof, [String, Array]],
13
+ cache_expires_in: [:typeof, [Integer, ActiveSupport::Duration]],
14
+ cached: [:oneof, [true, false]]
15
+ }
9
16
  attr_reader :conf
10
17
 
11
18
  def initialize(
@@ -191,7 +198,7 @@ module SvelteOnRails
191
198
  @conf.debug_log(debug?, component_paths[:name], "rendered and stored to cache (key: «#{cache_key}»)") do
192
199
  r = view_context.instance_eval(&block)
193
200
  unless @skip_caching
194
- @conf.redis_instance.set(cache_key, r)
201
+ @conf.redis_instance.set(cache_key, r, ex: redis_expiration_seconds)
195
202
  end
196
203
  r
197
204
  end
@@ -289,18 +296,17 @@ module SvelteOnRails
289
296
  raise "Unknown options: #{@options.keys - RENDER_OPTIONS.keys}. Valid options are: :#{RENDER_OPTIONS.keys.join(', :')}"
290
297
  end
291
298
  @options.each do |k, v|
292
- _v = RENDER_OPTIONS[k]
293
- if _v == :bool
294
- unless [true, false].include?(v)
295
- raise "[SOR] Invalid option: :#{k} must be true or false (boolean)."
296
- end
297
- elsif _v == :string_array
298
- unless [String, Array].include?(v.class)
299
- raise "[SOR] Invalid option: :#{k} must be a string or Array (list of strings)."
299
+ validation = RENDER_OPTIONS[k]
300
+ _v_type = validation.first
301
+ _v_opts = validation.second
302
+
303
+ if validation.first == :oneof
304
+ unless validation.second.include? v
305
+ raise "[SOR] Invalid option: :#{k} must be one of #{validation.second.join(', ')}"
300
306
  end
301
- elsif _v.is_a?(Array)
302
- unless _v.include?(v)
303
- raise "[SOR] Invalid option: :#{k} must be one of #{_v.join(', ')}"
307
+ elsif validation.first == :typeof
308
+ unless validation.second.include? v.class
309
+ raise "[SOR] Invalid option: :#{k} must be one of #{validation.second.join(', ')}"
304
310
  end
305
311
  else
306
312
  raise "[SOR] Unknown validation for option"
@@ -337,16 +343,17 @@ module SvelteOnRails
337
343
  @cache_key = begin
338
344
  fingerprint = (@conf.watch_changes? ? @conf.fingerprint(component_paths[:path], debug?, component_paths[:name]) : '')
339
345
 
340
- cache_key_raw = @view_dir + @component_name + @options.to_s +
346
+ cache_key_raw = @options.to_s +
341
347
  @cached_props.to_s + fingerprint + @options[:cache_key].to_s +
342
348
  (@cached_props.key?(:_uncached) ? "" : @html_options.to_s)
343
349
 
344
- "#{@conf.redis_namespace}:#{Digest::XXH64.hexdigest(cache_key_raw)}"
350
+ "#{@conf.redis_namespace}:#{@component_name.gsub('/','-')}:#{Digest::XXH64.hexdigest(cache_key_raw)}"
345
351
  end
346
352
  end
347
353
 
348
354
  def redis_expiration_seconds
349
- (conf.redis_cache_store[:expires_in] || @options[:expires_in] || 1.hour).to_i
355
+ ex = @options[:cache_expires_in] || conf.configs[:cache_expires_in] || 3.days
356
+ ex.to_i
350
357
  end
351
358
 
352
359
  end
@@ -13,12 +13,14 @@ module SvelteOnRails
13
13
 
14
14
  # Spawn the Node SSR child process only when we're really about to serve
15
15
  # HTTP. `after_initialize` runs at the end of boot, so Puma/Unicorn/etc.
16
- # are already loaded and the detection in `start_ssr_server?` is reliable.
16
+ # are already loaded and the detection in `serving_http?` is reliable.
17
17
  initializer "svelte-on-rails.initialize_ssr_client" do |app|
18
18
  app.config.after_initialize do
19
19
 
20
- if defined?(Rake) && Rake.respond_to?(:application) && Rake.application.top_level_tasks.any?
21
- SvelteOnRails::Lib::Utils.ssr_server_log("Skipping svelte-on-rails SSR-Server because of top level task: #{Rake.application.top_level_tasks.join(', ')}")
20
+ if !SvelteOnRails::BootContext.serving_http?
21
+ SvelteOnRails::Lib::Utils.ssr_server_log(
22
+ "Skipping svelte-on-rails SSR-Server (#{SvelteOnRails::BootContext.description})"
23
+ )
22
24
  $stdout.flush
23
25
  elsif SvelteOnRails::Configuration.instance.configs[:ssr]
24
26
  SvelteOnRails::SsrClient.instance
@@ -51,7 +53,7 @@ module SvelteOnRails
51
53
 
52
54
  rake_tasks do
53
55
  load File.expand_path("../../tasks/svelte_on_rails_tasks.rake", __FILE__)
56
+ load File.expand_path("../../tasks/cache_tasks.rake", __FILE__)
54
57
  end
55
-
56
58
  end
57
59
  end
@@ -143,15 +143,18 @@ module SvelteOnRails
143
143
  end
144
144
 
145
145
  def calling_view_dir
146
- rails_views_path = Rails.root.join('app', 'views').to_s
147
- raw_path_full = caller_locations.find do |loc|
148
- loc.to_s.include?(rails_views_path)
149
- end.to_s
150
-
151
- if raw_path_full.present?
152
- raw_path = raw_path_full.split(/:[0-9]+:in/).first
153
- File.dirname(raw_path[(rails_views_path.length + 1)..-1])
154
- end.to_s
146
+ rails_views_path = SvelteOnRails::ViewHelpers.rails_views_path
147
+ prefix_len = rails_views_path.length + 1
148
+
149
+ # Walk only a bounded slice of the stack; use loc.path (no string formatting).
150
+ loc = caller_locations(1, 60)&.find { |l| l.path&.start_with?(rails_views_path) }
151
+ return ''.freeze unless loc
152
+
153
+ File.dirname(loc.path[prefix_len..-1])
154
+ end
155
+
156
+ def self.rails_views_path
157
+ @rails_views_path ||= Rails.root.join('app', 'views').to_s
155
158
  end
156
159
 
157
160
  end
@@ -0,0 +1,156 @@
1
+ namespace :svelte_on_rails do
2
+ namespace :cache do
3
+
4
+ desc "Delete all svelte-on-rails cache keys from Redis (scoped to the configured redis_namespace)"
5
+ task clear: :environment do
6
+ conf = SvelteOnRails::Configuration.instance
7
+ redis = conf.redis_instance
8
+ namespace = conf.redis_namespace
9
+
10
+ unless redis
11
+ warn "svelte_on_rails:clear_cache — no redis_instance configured, nothing to do."
12
+ next
13
+ end
14
+
15
+ if Rails.env.production? && ENV["FORCE"] != "1"
16
+ print "You are about to delete all keys matching «#{namespace}:*» in PRODUCTION. Continue? (y/N) "
17
+ answer = STDIN.gets.to_s.strip.downcase
18
+ unless %w[y yes].include?(answer)
19
+ puts "Aborted."
20
+ next
21
+ end
22
+ end
23
+
24
+ pattern = "#{namespace}:*"
25
+ cursor = "0"
26
+ total_deleted = 0
27
+ batches = 0
28
+
29
+ puts "Scanning Redis for keys matching «#{pattern}» ..."
30
+
31
+ loop do
32
+ cursor, keys = redis.scan(cursor, match: pattern, count: 500)
33
+ if keys.any?
34
+ # UNLINK is non-blocking on Redis >= 4; fall back to DEL if not available.
35
+ deleted = begin
36
+ redis.unlink(*keys)
37
+ rescue Redis::CommandError
38
+ redis.del(*keys)
39
+ end
40
+ total_deleted += deleted
41
+ batches += 1
42
+ end
43
+ break if cursor == "0"
44
+ rescue => e
45
+ warn "svelte_on_rails:clear_cache — error during scan/delete: #{e.class}: #{e.message}"
46
+ break
47
+ end
48
+
49
+ puts "svelte_on_rails:clear_cache — deleted #{total_deleted} key(s) in #{batches} batch(es) under «#{pattern}»."
50
+ end
51
+
52
+ desc "Show all svelte-on-rails Redis keys with their memory footprint (scoped to redis_namespace). Env: LIMIT=n, SORT=size|key, PATTERN=extra-glob"
53
+ task show: :environment do
54
+ conf = SvelteOnRails::Configuration.instance
55
+ redis = conf.redis_instance
56
+ namespace = conf.redis_namespace
57
+
58
+ unless redis
59
+ warn "svelte_on_rails:show_cache — no redis_instance configured, nothing to show."
60
+ next
61
+ end
62
+
63
+ extra = ENV["PATTERN"].to_s.strip
64
+ pattern = extra.empty? ? "#{namespace}:*" : "#{namespace}:*#{extra}*"
65
+ limit = ENV["LIMIT"].to_s =~ /\A\d+\z/ ? ENV["LIMIT"].to_i : nil
66
+ sort_by = %w[size key].include?(ENV["SORT"]) ? ENV["SORT"] : "size"
67
+
68
+ puts "Scanning Redis for keys matching «#{pattern}» ..."
69
+
70
+ entries = [] # [{ key:, bytes:, ttl:, type: }]
71
+ cursor = "0"
72
+
73
+ loop do
74
+ cursor, keys = redis.scan(cursor, match: pattern, count: 500)
75
+
76
+ if keys.any?
77
+ # Pipeline MEMORY USAGE / TTL / TYPE for the whole batch.
78
+ results = redis.pipelined do |p|
79
+ keys.each do |k|
80
+ p.call(["MEMORY", "USAGE", k])
81
+ p.ttl(k)
82
+ p.type(k)
83
+ end
84
+ end
85
+
86
+ keys.each_with_index do |k, i|
87
+ bytes = results[i * 3]
88
+ ttl = results[i * 3 + 1]
89
+ type = results[i * 3 + 2]
90
+ entries << { key: k, bytes: bytes.to_i, ttl: ttl.to_i, type: type }
91
+ end
92
+ end
93
+
94
+ break if cursor == "0"
95
+ rescue => e
96
+ warn "svelte_on_rails:show_cache — error during scan: #{e.class}: #{e.message}"
97
+ break
98
+ end
99
+
100
+ if entries.empty?
101
+ puts "No keys found under «#{pattern}»."
102
+ next
103
+ end
104
+
105
+ entries.sort_by! { |e| sort_by == "size" ? -e[:bytes] : e[:key] }
106
+ shown = limit ? entries.first(limit) : entries
107
+
108
+ key_w = [shown.map { |e| e[:key].length }.max, 3].max
109
+ size_w = [shown.map { |e| human_bytes(e[:bytes]).length }.max, 4].max
110
+ ttl_w = [shown.map { |e| ttl_str(e[:ttl]).length }.max, 3].max
111
+ type_w = [shown.map { |e| e[:type].to_s.length }.max, 4].max
112
+
113
+ header = format("%-#{key_w}s %#{size_w}s %#{ttl_w}s %-#{type_w}s", "KEY", "SIZE", "TTL", "TYPE")
114
+ puts header
115
+ puts "-" * header.length
116
+
117
+ shown.each do |e|
118
+ puts format(
119
+ "%-#{key_w}s %#{size_w}s %#{ttl_w}s %-#{type_w}s",
120
+ e[:key], human_bytes(e[:bytes]), ttl_str(e[:ttl]), e[:type]
121
+ )
122
+ end
123
+
124
+ total_bytes = entries.sum { |e| e[:bytes] }
125
+ puts "-" * header.length
126
+ puts "Total: #{entries.size} key(s), #{human_bytes(total_bytes)} in RAM" \
127
+ "#{limit && entries.size > limit ? " (showing top #{limit} by #{sort_by})" : ""}"
128
+ end
129
+ end
130
+ end
131
+
132
+ # Helpers used by svelte_on_rails:show_cache
133
+ def human_bytes(n)
134
+ return "0 B" if n.nil? || n <= 0
135
+ units = %w[B KB MB GB TB]
136
+ i = (Math.log(n) / Math.log(1024)).floor
137
+ i = units.length - 1 if i >= units.length
138
+ format("%.2f %s", n.to_f / (1024 ** i), units[i])
139
+ end
140
+
141
+ def ttl_str(ttl)
142
+ case ttl
143
+ when -2 then "gone"
144
+ when -1 then "∞"
145
+ else
146
+ if ttl >= 86_400 then
147
+ "#{(ttl / 86_400.0).round(1)}d"
148
+ elsif ttl >= 3_600 then
149
+ "#{(ttl / 3_600.0).round(1)}h"
150
+ elsif ttl >= 60 then
151
+ "#{(ttl / 60.0).round(1)}m"
152
+ else
153
+ "#{ttl}s"
154
+ end
155
+ end
156
+ end
@@ -157,4 +157,4 @@ namespace :svelte_on_rails do
157
157
 
158
158
  end
159
159
 
160
- Rake::Task["assets:precompile"].enhance ["svelte_on_rails:precompile"]
160
+ Rake::Task["assets:precompile"].enhance ["svelte_on_rails:precompile"]
@@ -48,7 +48,6 @@ ssr_error_tag: true
48
48
 
49
49
  # redis_cache_store:
50
50
  # url: 'redis://localhost:6379/2'
51
- # expires_in: 90.minutes (=> default / fallback: 1 hour)
52
51
  # namespace: 'my-app-svelte-on-rails'
53
52
 
54
53
 
@@ -56,6 +55,10 @@ use_caching: false
56
55
  # this is the default for the #svelte view-helper.
57
56
  # When set to true, the redis gem is required.
58
57
 
58
+ cache_expires_in: 3.days
59
+ # ttl for cache keys
60
+ # default: 3.days
61
+
59
62
  debug: true
60
63
  # provides deeper logging with timestamps for performance improvements
61
64
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: svelte-on-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 22.2.0
4
+ version: 22.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Sedlmair
@@ -84,6 +84,7 @@ files:
84
84
  - lib/svelte_on_rails/installer/npm_sandbox.rb
85
85
  - lib/svelte_on_rails/installer/svelte.rb
86
86
  - lib/svelte_on_rails/installer/utils.rb
87
+ - lib/svelte_on_rails/lib/boot_context.rb
87
88
  - lib/svelte_on_rails/lib/cache_warmer.rb
88
89
  - lib/svelte_on_rails/lib/development_utils.rb
89
90
  - lib/svelte_on_rails/lib/fallback_renderer.rb
@@ -100,6 +101,7 @@ files:
100
101
  - lib/svelte_on_rails/ssr_client.rb
101
102
  - lib/svelte_on_rails/turbo_stream.rb
102
103
  - lib/svelte_on_rails/view_helpers.rb
104
+ - lib/tasks/cache_tasks.rake
103
105
  - lib/tasks/svelte_on_rails_tasks.rake
104
106
  - templates/config_base/app/frontend/ssr/ssr.js
105
107
  - templates/config_base/config/svelte_on_rails.yml