Class: SvelteOnRails::Configuration

Inherits:
Object
  • Object
show all
Includes:
Lib::WatchAssetChanges
Defined in:
lib/svelte_on_rails/configuration.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Lib::WatchAssetChanges

#build_status, #component_mtime_changed?, #fetch_source_files, #fingerprint, #manifest, #vite_build

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/svelte_on_rails/configuration.rb', line 15

def initialize

  @boot_key = SecureRandom.hex(3) # currently not used, more for debugging purposes
  @configs = redis_cache_store_configs

  @component_paths_cache = {}

  return unless defined?(Rails.root)

  config_path = Rails.root.join("config", "svelte_on_rails.yml")
  return unless File.exist?(config_path)

  environments = Dir[Rails.root.join('config', 'environments', '*.rb')]
                   .map { |file| File.basename(file, '.rb') }

  configs_base = YAML.load_file(config_path).deep_symbolize_keys

  # merge envrionment specific configs
  current_env = Rails.env.to_sym
  env_configs = configs_base.dup[current_env]
  merged_configs = configs_base.deep_merge(env_configs || {})

  # cleanup
  @configs = merged_configs.reject { |k, _| environments.include?(k.to_s) }

  # caching defaults
  if @configs[:redis_cache_store]
    store = @configs[:redis_cache_store]
    if store['expires_in'].is_a?(String)
      @configs[:redis_cache_store]['expires_in'] = parse_duration(
        store['expires_in']
      )
    end
    @redis_namespace = store[:namespace]
  end
  @redis_namespace ||= "svelte-on-rails:#{Rails.env rescue 'no-env'}"
  @configs[:skip_ssr_header] ||= 'X-Turbo-Request-ID'
  if defined? Redis
    @redis_instance = Redis.new(url: redis_cache_store[:url])
  end

  validate_configs
end

Instance Attribute Details

#component_paths_cacheObject

Returns the value of attribute component_paths_cache.



13
14
15
# File 'lib/svelte_on_rails/configuration.rb', line 13

def component_paths_cache
  @component_paths_cache
end

#configsObject

Returns the value of attribute configs.



13
14
15
# File 'lib/svelte_on_rails/configuration.rb', line 13

def configs
  @configs
end

#redis_namespaceObject

Returns the value of attribute redis_namespace.



13
14
15
# File 'lib/svelte_on_rails/configuration.rb', line 13

def redis_namespace
  @redis_namespace
end

#request_metricsObject

Returns the value of attribute request_metrics.



13
14
15
# File 'lib/svelte_on_rails/configuration.rb', line 13

def request_metrics
  @request_metrics
end

Class Method Details

.instanceObject



9
10
11
# File 'lib/svelte_on_rails/configuration.rb', line 9

def self.instance
  @instance ||= new
end

Instance Method Details

#assets_folder_pathObject



119
120
121
# File 'lib/svelte_on_rails/configuration.rb', line 119

def assets_folder_path
  rails_root.join('public', 'svelte-ssr')
end

#build_status_fileObject



127
128
129
# File 'lib/svelte_on_rails/configuration.rb', line 127

def build_status_file
  assets_folder_path.join('.vite', 'build-status.json')
end

#components_rootObject



115
116
117
# File 'lib/svelte_on_rails/configuration.rb', line 115

def components_root
  File.join(@configs[:vite_source_dir], @configs[:components_subdir])
end

#debug_log(debug, component_basename, subject, show_component_name: true, &block) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/svelte_on_rails/configuration.rb', line 71

def debug_log(debug, component_basename, subject, show_component_name: true, &block)
  msg = if show_component_name
          "  [SOR] #{component_basename}.svelte #{subject}"
        else
          "  [SOR] #{subject}"
        end
  if !block_given?
    Rails.logger.debug(msg)
  else
    if debug || @configs[:debug]
      r = nil
      sec = Benchmark.realtime do
        r = block.call
      end
      Rails.logger.debug("#{msg} (#{(sec * 1000.0).round(2)}ms)")
      r
    else
      block.call
    end
  end
end

#dev_module_map_pathObject



131
132
133
# File 'lib/svelte_on_rails/configuration.rb', line 131

def dev_module_map_path
  assets_folder_path.join('.vite', 'dev-module-map.json')
end

#manifest_json_pathObject



123
124
125
# File 'lib/svelte_on_rails/configuration.rb', line 123

def manifest_json_path
  assets_folder_path.join('.vite', 'manifest.json')
end

#node_bin_pathObject



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/svelte_on_rails/configuration.rb', line 135

def node_bin_path
  @node_bin_path ||= begin
                       n = ENV['SVELTE_ON_RAILS_NODE_BIN'] || 'node'

                       if n == 'node'
                         nvm_installed = false
                         nvm_dir = ENV['NVM_DIR'] || File.expand_path('~/.nvm')
                         nvm_installed ||= File.exist?("#{nvm_dir}/nvm.sh")

                         if nvm_installed
                           # Check for .nvmrc in the project root
                           project_root = rails_root || Dir.pwd
                           nvmrc_path = File.join(project_root, '.nvmrc')
                           use_nvmrc = File.exist?(nvmrc_path)

                           if use_nvmrc
                             # Read the version from .nvmrc
                             node_version = File.read(nvmrc_path).strip
                             # Ensure NVM is sourced and use the version from .nvmrc
                             command = "[ -s \"#{nvm_dir}/nvm.sh\" ] && . \"#{nvm_dir}/nvm.sh\" && nvm use #{node_version} > /dev/null 2>&1 && nvm which #{node_version}"
                           else
                             # Fallback to current NVM version
                             command = "[ -s \"#{nvm_dir}/nvm.sh\" ] && . \"#{nvm_dir}/nvm.sh\" && nvm which current"
                           end

                           node_path, status = Open3.capture2("bash -lc '#{command}'")

                           # Only update n if the command succeeded and output is non-empty
                           n = node_path.strip if status.success? && !node_path.strip.empty?
                         end
                       end

                       # Validate node_bin
                       unless n && !n.empty? && system("#{n} --version > /dev/null 2>&1")
                         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."
                       end

                       n
                     rescue StandardError => e
                       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."
                     end
end

#rails_root(root_url = nil) ⇒ Object



111
112
113
# File 'lib/svelte_on_rails/configuration.rb', line 111

def rails_root(root_url = nil)
  root_url || Rails.root
end

#redis_cache_storeObject



59
60
61
# File 'lib/svelte_on_rails/configuration.rb', line 59

def redis_cache_store
  (@configs[:redis_cache_store] || {}).transform_keys(&:to_sym)
end

#redis_instanceObject



63
64
65
# File 'lib/svelte_on_rails/configuration.rb', line 63

def redis_instance
  @redis_instance
end

#to_svelte_benchmark_log(subject, &block) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/svelte_on_rails/configuration.rb', line 93

def to_svelte_benchmark_log(subject, &block)
  msg = "  [SOR] to_svelte #{subject}"
  if !block_given?
    Rails.logger.debug(msg)
  else
    if @configs[:debug]
      r = nil
      sec = Benchmark.realtime do
        r = block.call
      end
      Rails.logger.debug("#{msg} (#{(sec * 1000.0).round(2)}ms)")
      r
    else
      block.call
    end
  end
end

#watch_changes?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/svelte_on_rails/configuration.rb', line 67

def watch_changes?
  @configs[:watch_changes] == true
end