Module: SvelteOnRails::ViewHelpers

Defined in:
lib/svelte_on_rails/view_helpers.rb

Instance Method Summary collapse

Instance Method Details

#svelte(component, props = {}, options: {}, wrapper_html: {}, **kw_props) ⇒ Object



5
6
7
8
9
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
104
105
106
# File 'lib/svelte_on_rails/view_helpers.rb', line 5

def svelte(component, props = {}, options: {}, wrapper_html: {}, **kw_props)

  start_time = Time.now

  config = SvelteOnRails::Configuration.instance

  if config.watch_changes?
    raise ArgumentError, "props must be a Hash, got #{props.class}" unless props.is_a?(Hash)
    raise ArgumentError, "props must not have a options key" if props.key?(:options)
    raise ArgumentError, "props must not have a wrapper_html key" if props.key?(:wrapper_html)
  end

  component_props = props.deep_merge(kw_props)

  caching = if !options[:cached].nil?
              options[:cached]
            elsif !config.configs[:use_caching].nil?
              config.configs[:use_caching]
            else
              false
            end

  support = SvelteOnRails::Lib::ViewHelperSupport.new(
    component, component_props, wrapper_html, options,
    request, calling_view_dir, config, caching, start_time
  )

  if support.ssr?
    if config.watch_changes? && !config.build_status['passed']
      sor_error_tag(support, wrapper_html, component_props, 'server-side-svelte-build-error', 'SVELTE BUILD FAILED')

    elsif caching
      support.set_request_metrics(:from_cache)
      if component_props.key?(:_uncached)

        # With Caching:
        # when we have uncached props, we do not cache the wrapper tag

        attr = support.tag_attributes(wrapper_html, component_props)
        r = (:div, attr) do
          support.render_cached(self) do
            rnd = support.render_svelte(@current_template)
            if rnd[:success]
              concat(rnd[:head].html_safe)
              concat(rnd[:html].html_safe)
              support.log_completed("returned from cache, with uncached props#{', (Fallback!)' if rnd[:fallback]}")
            else
              sor_error_tag(support, wrapper_html, component_props, 'server-side-svelte-render-error', 'SVELTE RENDER FAILED')
            end
          end
        end

      else

        # With Caching:
        # when all props are cached, we can cache the wrapper tag too
        # ... but using only cached props for making sure we don't cache any dynamic content

        log = 'returned from cache'
        res = support.render_cached(self) do
          rnd = support.render_svelte(@current_template)
          if rnd[:success]
            attr = support.tag_attributes(wrapper_html, support.cached_props)
            log = "rendered#{' (Fallback!) and stored to cache' if rnd[:fallback]}"
            r = (:div, attr) do
              concat(rnd[:head].html_safe)
              concat(rnd[:html].html_safe)
            end

            r
          else
            log = "ERROR"
            sor_error_tag(support, wrapper_html, component_props, 'server-side-svelte-render-error', 'SVELTE RENDER FAILED')
          end
        end
        support.log_completed(log)
        res
      end
    else

      # Without caching:
      # just render

      rnd = support.render_svelte(@current_template)
      r = if rnd[:success]
            attr = support.tag_attributes(wrapper_html, component_props)
            (:div, attr) do
              concat(rnd[:head].html_safe)
              concat(rnd[:html].html_safe)
            end
          else
            sor_error_tag(support, wrapper_html, component_props, 'server-side-svelte-render-error', 'SVELTE RENDER FAILED')
          end

      support.log_completed("Rendered#{rnd[:fallback] ? ' (Fallback!)' : ''} #{'as empty element that will be mounted on the client side' unless support.ssr?}")
      r
    end

  else
    render_empty_tag(support, wrapper_html, component_props)
  end
end