Reaktive DOM-Updates mit Ruby.
Live-Demo unter rdom .fly.dev
Einbettungsdemo unter rdom .netlify.app
Dies ist ein grundlegendes Experiment mit einem serverseitigen VDOM in Ruby. Eine vollständigere Implementierung finden Sie unter Mayu Live. Ich hatte einige Ideen, die ich unbedingt erforschen musste, und das ist das Ergebnis.
Stellen Sie sicher, dass Sie Ruby 3.2 und Bundler haben, und führen Sie dann Folgendes aus:
bundle install
So starten Sie den Server:
ruby config.ru
Dieses Ding wird mit einem HTTP/2-Server geliefert. Starten Sie es mit ruby config.ru
.
Standardmäßig bindet es an https://localhost:8080
, kann aber geändert werden, indem die Umgebungsvariable rdom _BIND
wie folgt festgelegt wird: rdom _BIND="https://[::]" ruby config.ru
.
Dies sind die einzigen HTML-Zeilen, die Sie zum Mounten einer App benötigen.
< script type =" module " src =" https://rdom.fly.dev/ rdom .js " > </ script >
< rdom -embed src =" https://rdom.fly.dev/. rdom " > </ rdom -embed >
Sie können bin/transform
verwenden, um die transformierte Ausgabe einer Haml-Datei anzuzeigen.
Beispiel:
bin/transform app/List.haml
Dieses Repository enthält eine reaktive Signalbibliothek, die von SolidJS, Preact Signals und Reactively inspiriert ist.
Damit erstellte Apps können nur gestreamt werden. Der Server versucht niemals, den HTML-Code für die erste Anfrage zu erstellen. Wenn Sie in der ersten Anfrage HTML bereitstellen müssen, schauen Sie sich Mayu Live an.
Wenn die Verbindung unterbrochen wird, geht der gesamte Status verloren. Für einen Versuch, etwas Zuverlässigeres zu versuchen, schauen Sie sich Mayu Live an.
Alle statischen DOM-Bäume werden in benutzerdefinierte Elemente extrahiert. Wenn Sie also schreiben:
- items = %w[foo bar baz]
% ul
= items.map do |item |
% li = item
Dann wird dieser Code generiert:
# frozen_string_literal: true
class self :: Component < VDOM :: Component :: Base
rdom _Partials = [
VDOM :: CustomElement [
:" rdom -elem-app꞉꞉my-component.haml-0" ,
'<ul><slot id="slot0"></slot></ul>'
] ,
VDOM :: CustomElement [
:" rdom -elem-app꞉꞉my-component.haml-1" ,
'<li><slot id="slot0"></slot></li>'
]
]
def render
items = %w[ foo bar baz ]
H [
rdom _Partials [ 0 ] ,
slots : {
slot0 : items . map { | item | H [ rdom _Partials [ 1 ] , slots : { slot0 : item } ] }
}
]
end
end
Der Browser gibt Ihnen Folgendes:
< rdom -elem-my-component .haml-0 >
#shadow-dom
< ul > < slot > </ slot > </ ul >
< li >
< slot id =" slot0 " >
< rdom -elem-my-component .haml-1 > ↴
< rdom -elem-my-component .haml-1 > ↴
< rdom -elem-my-component .haml-1 > ↴
</ slot >
</ li >
< rdom -elem-my-component .haml-1 >
#shadow-dom
< li >
< slot id =" slot0 " >
< #text > ↴
</ slot >
</ li >
foo
</ rdom -elem-my-component .haml-1 >
< rdom -elem-my-component .haml-1 >
#shadow-dom
< li >
< slot id =" slot0 " >
< #text > ↴
</ slot >
</ li >
bar
</ rdom -elem-my-component .haml-1 >
< rdom -elem-my-component .haml-1 >
#shadow-dom
< li >
< slot id =" slot0 " >
< #text > ↴
</ slot >
</ li >
baz
</ rdom -elem-my-component .haml-1 >
</ rdom -elem-my-component .haml-0 >
Jedem Slot im Schatten-DOM werden seine Knoten zugewiesen, wenn untergeordnete Elemente aktualisiert werden.
Das ist aus mehreren Gründen gut:
Jedes benutzerdefinierte Element hat :host { display: contents; }
um Interferenzen mit Flex und Gitter zu vermeiden.