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
58
59
# 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 = {}
  @request_metrics = {}

  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
  validate_npm_packages
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



121
122
123
# File 'lib/svelte_on_rails/configuration.rb', line 121

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

#build_status_fileObject



129
130
131
# File 'lib/svelte_on_rails/configuration.rb', line 129

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

#components_rootObject



117
118
119
# File 'lib/svelte_on_rails/configuration.rb', line 117

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



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

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



133
134
135
# File 'lib/svelte_on_rails/configuration.rb', line 133

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

#initialize_request_metrics(request_uuid) ⇒ Object



180
181
182
183
184
185
186
187
188
# File 'lib/svelte_on_rails/configuration.rb', line 180

def initialize_request_metrics(request_uuid)
  return if request_uuid == @request_metrics[:request_uuid]

  @request_metrics = {
    request_uuid: request_uuid,
    total_time: 0.0
  }

end

#manifest_json_pathObject



125
126
127
# File 'lib/svelte_on_rails/configuration.rb', line 125

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

#node_bin_pathObject



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
177
178
# File 'lib/svelte_on_rails/configuration.rb', line 137

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



113
114
115
# File 'lib/svelte_on_rails/configuration.rb', line 113

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

#redis_cache_storeObject



61
62
63
# File 'lib/svelte_on_rails/configuration.rb', line 61

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

#redis_instanceObject



65
66
67
# File 'lib/svelte_on_rails/configuration.rb', line 65

def redis_instance
  @redis_instance
end

#to_svelte_benchmark_log(subject, &block) ⇒ Object



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

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)


69
70
71
# File 'lib/svelte_on_rails/configuration.rb', line 69

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