diff --git a/scalive/core/src/scalive/LiveView.scala b/scalive/core/src/scalive/LiveView.scala index d3f167c..f3c3bab 100644 --- a/scalive/core/src/scalive/LiveView.scala +++ b/scalive/core/src/scalive/LiveView.scala @@ -4,9 +4,7 @@ import zio.* import zio.stream.* trait LiveView[Msg, Model]: - def init: Task[Model] - def update(model: Model): Msg => Task[Model] + def init: Model | Task[Model] + def update(model: Model): Msg => Model | Task[Model] def view(model: Dyn[Model]): HtmlElement def subscriptions(model: Model): ZStream[Any, Nothing, Msg] - - given [T]: Conversion[T, Task[T]] = ZIO.succeed(_) diff --git a/scalive/zio/src/scalive/LiveRouter.scala b/scalive/zio/src/scalive/LiveRouter.scala index 8bcf366..c71f221 100644 --- a/scalive/zio/src/scalive/LiveRouter.scala +++ b/scalive/zio/src/scalive/LiveRouter.scala @@ -26,7 +26,7 @@ final case class LiveRoute[A, Msg, Model]( s"phx-${Base64.getUrlEncoder().withoutPadding().encodeToString(Random().nextBytes(12))}" val token = Token.sign("secret", id, "") for - initModel <- lv.init + initModel <- normalize(lv.init) el = lv.view(Var(initModel)) _ = el.syncAll() yield Response.html( diff --git a/scalive/zio/src/scalive/Socket.scala b/scalive/zio/src/scalive/Socket.scala index 33478a2..327aa44 100644 --- a/scalive/zio/src/scalive/Socket.scala +++ b/scalive/zio/src/scalive/Socket.scala @@ -27,7 +27,7 @@ object Socket: inbox <- Queue.bounded[(Payload.Event, WebSocketMessage.Meta)](4) outHub <- Hub.unbounded[(Payload, WebSocketMessage.Meta)] - initModel <- lv.init + initModel <- normalize(lv.init) modelVar = Var(initModel) el = lv.view(modelVar) ref <- Ref.make((modelVar, el)) @@ -52,7 +52,8 @@ object Socket: s"No binding found for event ID ${event.event}" ) ) - updatedModel <- lv.update(modelVar.currentValue)(f(event.params)) + updatedModel <- + normalize(lv.update(modelVar.currentValue)(f(event.params))) _ = modelVar.set(updatedModel) _ <- lvStreamRef.set(lv.subscriptions(updatedModel)) diff = el.diff() @@ -63,7 +64,7 @@ object Socket: serverFiber <- serverMsgStream.runForeach { (msg, meta) => for (modelVar, el) <- ref.get - updatedModel <- lv.update(modelVar.currentValue)(msg) + updatedModel <- normalize(lv.update(modelVar.currentValue)(msg)) _ = modelVar.set(updatedModel) diff = el.diff() payload = Payload.Diff(diff) diff --git a/scalive/zio/src/scalive/ZIOHelpers.scala b/scalive/zio/src/scalive/ZIOHelpers.scala new file mode 100644 index 0000000..c791944 --- /dev/null +++ b/scalive/zio/src/scalive/ZIOHelpers.scala @@ -0,0 +1,8 @@ +package scalive + +import zio.* + +private def normalize[A](value: A | Task[A]): Task[A] = + value match + case t: Task[?] @unchecked => t.asInstanceOf[Task[A]] + case v => ZIO.succeed(v.asInstanceOf[A])