Class: SvelteOnRails::Lib::ViewHelperSupport
- Inherits:
-
Object
- Object
- SvelteOnRails::Lib::ViewHelperSupport
- Defined in:
- lib/svelte_on_rails/lib/view_helper_support.rb
Constant Summary collapse
- RENDER_OPTIONS =
{ ssr: [true, false, :auto], hydrate: :bool, debug: :bool, cache_key: :string_array, expires_in: :integer, cached: :bool }
Instance Attribute Summary collapse
-
#conf ⇒ Object
readonly
Returns the value of attribute conf.
Instance Method Summary collapse
- #component_paths ⇒ Object
- #debug? ⇒ Boolean
-
#initialize(component, props, html_options, options, request, view_dir, config, caching = false, start_time) ⇒ ViewHelperSupport
constructor
A new instance of ViewHelperSupport.
- #log_completed(message) ⇒ Object
- #render_cached(view_context, &block) ⇒ Object
- #request_metrics ⇒ Object
- #set_request_metrics(action_key) ⇒ Object
- #ssr? ⇒ Boolean
- #tag_attributes(html_options, svelte_props) ⇒ Object
Constructor Details
#initialize(component, props, html_options, options, request, view_dir, config, caching = false, start_time) ⇒ ViewHelperSupport
Returns a new instance of ViewHelperSupport.
10 11 12 13 14 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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 10 def initialize( component, props, , , request, view_dir, config, caching = false, start_time ) @start_time = start_time @conf = config @utils = SvelteOnRails::Lib::Utils @options = @component_name = component @view_dir = view_dir @request = request @props = props @html_options = @ssr = resolve_ssr?(request) return unless @ssr if @conf.watch_changes? # check file existence and capitalization p = component_paths unless File.exist?(Rails.root.join(p[:path])) raise <<~TEXT [SOR] Source file not found: «#{p[:path]}» TEXT end if p[:path][0..9] == 'app/views/' if !p[:file_basename].match?(/^[A-Z][A-Za-z0-9]+$/) && !p[:file_basename].match?(/^[a-z0-9][a-z0-9_]+$/) raise <<~TEXT [SOR] Invalid filename: «#{p[:file_basename]}» Component names must be CamelCased or under_scored and must be prefixed by underscore. TEXT end elsif !p[:file_basename].match?(/^[A-Z][A-Za-z0-9]+$/) raise <<~TEXT [SOR] Invalid filename: «#{p[:file_basename]}» Component names must be CamelCased. TEXT end full_path = Rails.root.join(p[:path]) dir, wanted = full_path.dirname.to_s, full_path.basename.to_s unless Dir.children(dir).include?(wanted) raise "ERROR: Incorrect capitalisation: «#{p[:path]}»" end if !@conf.manifest_json_path.exist? || !@conf.dev_module_map_path.exist? || @conf.build_status['mtime'].to_f != @utils.manifest_file_mtime || # if a developer has run build from the console, we must update the build-status object # this is importand for having reliable error-messages (!@conf.build_status['passed'] && !request_metrics[:build_tried_for_error_message]) # when build has failed the developer sees the error message # at this point it is importand to see the build-error in the logs # but only ONCE for a request, so we check metrics too run_vite_build set_request_metrics(:build_tried_for_error_message) return unless @conf.build_status['passed'] end # now we are sure to have a valid manifest # and are able to collect the dependend source files, # check theyr mtime # and run a build if something has changed (is only the case if the build above not was run) ensure_valid_component_and_manifest!(component) if @conf.component_mtime_changed?(component_paths[:path], debug?, component_paths[:file_basename]) run_vite_build end # finally, validate the given options end if caching @cached_content = @conf.debug_log(debug?, component_paths[:name], "Fetch Cache") do ck = (@conf.watch_changes? ? cache_key_fresh : cache_key) @conf.redis_instance.get(ck) end return if @cached_content elsif @conf.watch_changes? raise '[SOR] :expires_in is not allowed for this helper' if @options.key?(:expires_in) raise '[SOR] :cache_key is not allowed for this helper' if @options.key?(:cache_key) end end |
Instance Attribute Details
#conf ⇒ Object (readonly)
Returns the value of attribute conf.
8 9 10 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 8 def conf @conf end |
Instance Method Details
#component_paths ⇒ Object
105 106 107 108 109 110 111 112 113 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 105 def component_paths if @conf.watch_changes? @component_paths ||= @utils.component_paths_uncached(@component_name, @view_dir) else key = "#{@component_name}_#{@view_dir}" @conf.component_paths_cache[key] ||= @utils.component_paths_uncached(@component_name, @view_dir) end end |
#debug? ⇒ Boolean
141 142 143 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 141 def debug? @options[:debug] end |
#log_completed(message) ⇒ Object
149 150 151 152 153 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 149 def log_completed() ms = ((Time.now - @start_time) * 1000) @conf.request_metrics[:total_time] += ms Rails.logger.info " [SOR] #{component_paths[:name]}.svelte #{} (#{ms.round(1)}ms)" end |
#render_cached(view_context, &block) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 155 def render_cached(view_context, &block) # increase expired time @conf.redis_instance.expire(cache_key, redis_expiration_seconds) # render res = if @cached_content msg = "returned from cache" @cached_content.html_safe else msg = "Rendered" @skip_caching = false @conf.debug_log(debug?, component_paths[:name], "rendered and stored to cache (key: «#{cache_key}»)") do r = view_context.instance_eval(&block) unless @skip_caching @conf.redis_instance.set(cache_key, r) end r end end log_completed(msg) res end |
#request_metrics ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 182 def request_metrics @conf.request_metrics ||= {} _req_id = @conf.request_metrics[:request_uuid] if @request.uuid != _req_id @conf.request_metrics = { request_uuid: @request.uuid, total_time: 0.0 } end @conf.request_metrics end |
#set_request_metrics(action_key) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 196 def set_request_metrics(action_key) if @conf.watch_changes? && ![ :build, :build_failed, :render_failed, :from_cache, :empty, :rendered, :build_tried_for_error_message, :ssr_server_unreachable ].include?(action_key) raise "[SOR] set_request_metrics: invalid action_key" end request_metrics @conf.request_metrics[action_key] ||= 0 @conf.request_metrics[action_key] += 1 end |
#ssr? ⇒ Boolean
145 146 147 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 145 def ssr? @ssr end |
#tag_attributes(html_options, svelte_props) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/svelte_on_rails/lib/view_helper_support.rb', line 115 def tag_attributes(, svelte_props) ht_opts = .deep_symbolize_keys.deep_merge( { data: { component: component_paths[:vite_path], controller: 'svelte-on-rails' } } ) cl = "svelte-component #{ht_opts[:class]}".split(' ') _cl = 'svelte-' + component_paths[:name].underscore.gsub('_', '-') cl.push(_cl) unless cl.include?(_cl) tnl = SvelteOnRails::Lib::ToSvelteTranslations.instance _tnl = tnl.cached_translations(I18n.locale, :to_svelte_props, nil) svelte_props[:_translations] = _tnl if _tnl svelte_props[:test] = 'hello' #svelte_props = {my: :joke} ht_opts[:class] = cl.compact.join(' ') ht_opts[:data][:props] = svelte_props.to_json ht_opts[:data][:svelte_status] = 'do-not-hydrate-me' if @options[:hydrate] == false ht_opts end |