Stream events and responses

This commit is contained in:
Paul-Henri Froidmont 2025-09-03 04:14:50 +02:00
parent dc3cc0ac07
commit fcc5f1799e
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
9 changed files with 233 additions and 153 deletions

View file

@ -1,3 +1,6 @@
package scalive
package playground
import scalive.*
final case class MyModel(
@ -6,14 +9,13 @@ final case class MyModel(
elems: List[Elem] = List.empty)
final case class Elem(name: String, age: Int)
class TestView(initialModel: MyModel) extends LiveView[String, TestView.Event]:
class TestView(initialModel: MyModel) extends LiveView[TestView.Event]:
import TestView.Event.*
private val modelVar = Var[MyModel](initialModel)
override def handleServerEvent(e: TestView.Event): Unit =
e match
case UpdateModel(f) => modelVar.update(f)
def handleEvent =
case UpdateModel(f) => modelVar.update(f)
val el: HtmlElement =
div(

View file

@ -1,5 +1,12 @@
package scalive
package playground
import scalive.*
import zio.json.JsonCodec
import zio.json.*
extension (lv: LiveView[?])
def renderHtml: String =
HtmlBuilder.build(lv.el)
@main
def main =
@ -10,20 +17,19 @@ def main =
Elem("c", 30)
)
)
val s = Socket("", "", TestView(initModel))
val lv = TestView(initModel)
println("Init")
println(s.renderHtml())
s.syncClient
s.syncClient
println(lv.renderHtml)
println(lv.diff().toJsonPretty)
println("Edit class attribue")
s.lv.handleServerEvent(
lv.handleEvent(
TestView.Event.UpdateModel(_.copy(cls = "text-lg"))
)
s.syncClient
println(lv.diff().toJsonPretty)
println("Edit first and last")
s.lv.handleServerEvent(
lv.handleEvent(
TestView.Event.UpdateModel(
_.copy(elems =
List(
@ -34,11 +40,11 @@ def main =
)
)
)
s.syncClient
println(s.renderHtml())
println(lv.diff().toJsonPretty)
println(lv.diff().toJsonPretty)
println("Add one")
s.lv.handleServerEvent(
lv.handleEvent(
TestView.Event.UpdateModel(
_.copy(elems =
List(
@ -50,11 +56,11 @@ def main =
)
)
)
s.syncClient
println(s.renderHtml())
println(lv.diff().toJsonPretty)
println(lv.renderHtml)
println("Remove first")
s.lv.handleServerEvent(
lv.handleEvent(
TestView.Event.UpdateModel(
_.copy(elems =
List(
@ -65,11 +71,11 @@ def main =
)
)
)
s.syncClient
println(s.renderHtml())
println(lv.diff().toJsonPretty)
println(lv.renderHtml)
println("Remove all")
s.lv.handleServerEvent(
lv.handleEvent(
TestView.Event.UpdateModel(
_.copy(
cls = "text-lg",
@ -78,7 +84,7 @@ def main =
)
)
)
s.syncClient
s.syncClient
println(s.renderHtml())
println(lv.diff().toJsonPretty)
println(lv.diff().toJsonPretty)
println(lv.renderHtml)
end main

View file

@ -1,6 +1,11 @@
package scalive
trait LiveView[ClientEvt, ServerEvent]:
def handleClientEvent(evt: ClientEvt): Unit = ()
def handleServerEvent(evt: ServerEvent): Unit = ()
trait LiveView[Event]:
def handleEvent: Event => Unit
val el: HtmlElement
private[scalive] def diff(trackUpdates: Boolean = true): Diff =
el.syncAll()
val diff = DiffBuilder.build(el, trackUpdates = trackUpdates)
el.setAllUnchanged()
diff

View file

@ -1,39 +0,0 @@
package scalive
import zio.json.*
final case class Socket[CliEvt: JsonCodec, SrvEvt](
id: String,
token: String,
lv: LiveView[CliEvt, SrvEvt]):
val clientEventCodec = JsonCodec[CliEvt]
private var clientInitialized = false
lv.el.syncAll()
def renderHtml(rootLayout: HtmlElement => HtmlElement = identity): String =
lv.el.syncAll()
HtmlBuilder.build(
rootLayout(
div(
idAttr := id,
phx.session := token,
lv.el
)
)
)
def syncClient: Unit =
lv.el.syncAll()
println(DiffBuilder.build(lv.el, trackUpdates = clientInitialized).toJsonPretty)
clientInitialized = true
lv.el.setAllUnchanged()
def diff: Diff =
lv.el.syncAll()
val diff = DiffBuilder.build(lv.el, trackUpdates = clientInitialized)
clientInitialized = true
lv.el.setAllUnchanged()
diff
end Socket

View file

@ -15,8 +15,15 @@ final case class WebSocketMessage(
// LiveView instance id
topic: String,
eventType: String,
payload: WebSocketMessage.Payload)
payload: WebSocketMessage.Payload):
val meta = WebSocketMessage.Meta(joinRef, messageRef, topic)
object WebSocketMessage:
final case class Meta(
joinRef: Option[Int],
messageRef: Int,
topic: String)
given JsonCodec[WebSocketMessage] = JsonCodec[Json].transformOrFail(
{
case Json.Arr(