Class: BridgetownLitRenderer::Renderer
- Inherits:
-
Object
- Object
- BridgetownLitRenderer::Renderer
- Includes:
- Singleton
- Defined in:
- lib/bridgetown-lit-renderer/renderer.rb
Class Attribute Summary collapse
-
.authtoken ⇒ Object
Returns the value of attribute authtoken.
-
.serverpid ⇒ Object
Returns the value of attribute serverpid.
-
.serverport ⇒ Object
Returns the value of attribute serverport.
Instance Attribute Summary collapse
-
#site ⇒ Object
Returns the value of attribute site.
Class Method Summary collapse
Instance Method Summary collapse
- #cache ⇒ Object
- #call_http_server(payload) ⇒ Object
- #entry_key(entry) ⇒ Object
- #esbuild(code) ⇒ Object
- #js_code_block(entry, code) ⇒ Object
- #render(code, data:, entry:) ⇒ Object
- #reset ⇒ Object
Class Attribute Details
.authtoken ⇒ Object
Returns the value of attribute authtoken.
11 12 13 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 11 def authtoken @authtoken end |
.serverpid ⇒ Object
Returns the value of attribute serverpid.
11 12 13 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 11 def serverpid @serverpid end |
.serverport ⇒ Object
Returns the value of attribute serverport.
11 12 13 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 11 def serverport @serverport end |
Instance Attribute Details
#site ⇒ Object
Returns the value of attribute site.
14 15 16 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 14 def site @site end |
Class Method Details
.start_node_server(node_modules_path) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 16 def self.start_node_server(node_modules_path) return if serverpid self.authtoken = SecureRandom.hex(64) self.serverport = RandomPort::Pool.new.acquire self.serverpid = spawn( { "LIT_SSR_SERVER_PORT" => serverport.to_s, "LIT_SSR_AUTH_TOKEN" => authtoken, "NODE_PATH" => node_modules_path, }, "node #{File.("../../src/serve.js", __dir__)}", pgroup: true ) Process.detach serverpid sleep 0.5 end |
.stop_node_server ⇒ Object
35 36 37 38 39 40 41 42 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 35 def self.stop_node_server return unless serverpid Process.kill("SIGTERM", -Process.getpgid(serverpid)) self.serverpid = nil self.serverport = nil rescue Errno::ESRCH, Errno::EPERM, Errno::ECHILD # rubocop:disable Lint/SuppressedException end |
Instance Method Details
#cache ⇒ Object
53 54 55 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 53 def cache @cache ||= Bridgetown::Cache.new("LitSSR") end |
#call_http_server(payload) ⇒ Object
57 58 59 60 61 62 63 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 57 def call_http_server(payload) Faraday.post( "http://127.0.0.1:#{self.class.serverport}", payload, "Authorization" => "Bearer #{self.class.authtoken}" ).body.force_encoding("utf-8") end |
#entry_key(entry) ⇒ Object
44 45 46 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 44 def entry_key(entry) entry.start_with?("./") ? File.stat(site.in_root_dir(entry)).mtime : entry end |
#esbuild(code) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 65 def esbuild(code) raise "You must first assign the `site' accessor" unless site unless @esbuild_notice_printed Bridgetown.logger.info "Lit SSR:", "Bundling with esbuild..." @esbuild_notice_printed = true end # TODO: shouldn't this use the sidecar Node process as well? IO.popen(["node", site.in_root_dir("./config/lit-ssr.config.js")], "r+") do |pipe| pipe.puts({ code: code }.to_json) pipe.close_write pipe.read end end |
#js_code_block(entry, code) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 109 def js_code_block(entry, code) entry_import = "import #{entry.to_json}" <<~JS import { render } from "@lit-labs/ssr/lib/render-with-global-dom-shim.js" import { html } from "lit" #{entry_import} const ssrResult = render(html` #{code} `); let ret = [] for (const chunk of ssrResult) { ret.push(chunk) } ret.join("") JS end |
#render(code, data:, entry:) ⇒ Object
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 107 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 81 def render(code, data:, entry:) raise "You must first assign the `site' accessor" unless site cache_key = "esbuild-#{code}#{entry}#{entry_key(entry)}" built_code = cache.getset(cache_key) { esbuild(js_code_block(entry, code)) } unless @render_notice_printed Bridgetown.logger.info "Lit SSR:", "Rendering components..." @render_notice_printed = true end self.class.start_node_server(site.in_root_dir("node_modules")) output = call_http_server("const data = #{data.to_json}; #{built_code}") if output == "SCRIPT NOT VALID!" output = <<~HTML <ssr-error style="display:block; padding:0.3em 0.5em; color:white; background:maroon; font-weight:bold"> Lit SSR error in #{entry}, see logs </ssr-error> HTML cache.delete(cache_key) end output.html_safe end |
#reset ⇒ Object
48 49 50 51 |
# File 'lib/bridgetown-lit-renderer/renderer.rb', line 48 def reset @esbuild_notice_printed = false @render_notice_printed = false end |