-
-
Notifications
You must be signed in to change notification settings - Fork 8
Description
summary
I'm trying to render a lustre document directly to string, SSR style. This works fine when using lustre on its own, using something to the effect of
import lustre/element
import lustre/element/html
import gleam/io
pub fn main() {
html.html(...)
|> element.to_document_string()
|> io.println
}However when using sketch and sketch_lustre this results in the program crashing at runtime error with the following stack trace:
runtime error: Erlang error
An error occurred outside of Gleam.
erlang:error(Badarg)
stacktrace:
ets.lookup unknown source
sketch_global_ffi.get_stylesheet /root/lustre_bug/build/dev/erlang/sketch_lustre/_gleam_artefacts/sketch/lustre/internals/sketch_global_ffi.erl:39
sketch/lustre/element.class_name src/sketch/lustre/element.gleam:82
sketch/lustre/element.element src/sketch/lustre/element.gleam:37
lustre_bug.-render_sketch_ssr/0-fun-0- src/lustre_bug.gleam:33
sketch/lustre.ssr src/sketch/lustre.gleam:219
lustre_bug.main src/lustre_bug.gleam:74
It's possible this is because I am not setting up/initializing the stylesheet correctly. However I am trying to follow the examples given in the sketch_lustre documentation and on the sketch homepage to the best of my ability-- as an aside, both of those example code snippets are in fact broken and do not compile on latest versions.
detailed explanation/troubleshooting/reproduction
Anyway, I threw together a reproduction of the issue to explain what I tried and what's breaking in more detail: https://github.com/kwshi/bug-reports/tree/main/gleam-sketch-lustre-ssr. I'm also pasting the code here for your reference:
import argv
import gleam/io
import lustre/element
import lustre/element/html
import sketch
import sketch/css
import sketch/lustre as sketch_lustre
import sketch/lustre/element/html as sketch_html
fn render_vanilla() {
html.html([], [
html.head([], [html.title([], "hello lustre")]),
html.body([], [html.text("foo bar")]),
])
}
fn render_sketch_ssr() {
use <- sketch_lustre.ssr()
sketch_html.html([], [
sketch_html.head([], [sketch_html.title([], "hello lustre")]),
sketch_html.body(css.class([css.color("red")]), [], [
sketch_html.text("foo bar"),
]),
])
}
fn render_sketch_manual(stylesheet: sketch.StyleSheet) {
use <- sketch_lustre.render(stylesheet, [sketch_lustre.node()])
sketch_html.html([], [
sketch_html.head([], [sketch_html.title([], "hello lustre")]),
sketch_html.body(css.class([css.color("red")]), [], [
sketch_html.text("foo bar"),
]),
])
}
fn render_mix_ssr() {
use <- sketch_lustre.ssr()
render_vanilla()
}
fn render_mix_manual(stylesheet: sketch.StyleSheet) {
use <- sketch_lustre.render(stylesheet, [sketch_lustre.node()])
render_vanilla()
}
fn render(stylesheet: sketch.StyleSheet) {
case argv.load().arguments {
["vanilla"] -> render_vanilla()
["sketch-ssr"] -> render_sketch_ssr()
["sketch-manual"] -> render_sketch_manual(stylesheet)
["mix-ssr"] -> render_mix_ssr()
["mix-manual"] -> render_mix_manual(stylesheet)
_ ->
panic as "invalid case: run with one of `vanilla`, `sketch-ssr`, `sketch-manual`, `mix-ssr`, `mix-manual`"
}
}
pub fn main() {
let assert Ok(stylesheet) = sketch_lustre.setup()
render(stylesheet)
|> element.to_document_string
|> io.println
}Basically, here are five different variations of the same basic render function:
render_vanillais the plain lustre version without sketchrender_sketch_ssrrenders elements usingsketch/lustre/element/htmlwrapped withsketch/lustre.ssrrender_sketch_manualrenders elements usingsketch/lustre/element/htmlwrapped withsketch/lustre.renderrender_mix_ssrrenders elements using plainlustre/element/htmlbut wraps it insketch/lustre.ssranyway, because I guess why notrender_mix_manualrenders elements using plainlustre/element/htmlwrapped withsketch/lustre.render
The last two are maybe kind of pointless but I included anyway just to poke around. The first (vanilla) is included just to demonstrate that things work fine without sketch. The ssr example results in the crash, whereas the manual example does not. It looks from the source code that ssr is essentially just calling render behind the scenes after retrieving the stylesheet from some global store (via global.get_stylesheet()) which is supposed to be created by setup, and this appears to be what's broken, as also indicated by the error stacktrace.
Anyway, please let me know if this is a bug, or if I'm just missing something about the correct way to use sketch. I am new to Gleam and have also never worked with any of the other BEAM languages before (Elixir, Erlang) so I also don't really understand how to troubleshoot these errors occurring seemingly outside Gleam and rather in the Erlang runtime; narrowing it down to get_stylesheet/set_stylesheet seems to be the best guess I've got.