diff --git a/build.sbt b/build.sbt index b4bcbd0..571c949 100644 --- a/build.sbt +++ b/build.sbt @@ -111,7 +111,7 @@ .jvmSettings( libraryDependencies += "org.apache.poi" % "poi-ooxml" % "5.2.1" ) - .dependsOn(core) + .dependsOn(core, `tapir-support`) lazy val `scenarios-ui` = project .in(file("ui/scenarios")) diff --git a/build.sbt b/build.sbt index b4bcbd0..571c949 100644 --- a/build.sbt +++ b/build.sbt @@ -111,7 +111,7 @@ .jvmSettings( libraryDependencies += "org.apache.poi" % "poi-ooxml" % "5.2.1" ) - .dependsOn(core) + .dependsOn(core, `tapir-support`) lazy val `scenarios-ui` = project .in(file("ui/scenarios")) diff --git a/tapir/shared/src/main/scala/works/iterative/tapir/ClientEndpointFactory.scala b/tapir/shared/src/main/scala/works/iterative/tapir/ClientEndpointFactory.scala index 42ff9e1..be3e2a3 100644 --- a/tapir/shared/src/main/scala/works/iterative/tapir/ClientEndpointFactory.scala +++ b/tapir/shared/src/main/scala/works/iterative/tapir/ClientEndpointFactory.scala @@ -8,7 +8,9 @@ object Client: def apply[I, E, O](f: I => IO[E, O]): Client[I, E, O] = f - extension [I, E, O](f: Client[I, E, O]) def apply(i: I): IO[E, O] = f(i) + extension [I, E, O](f: Client[I, E, O]) + def apply(i: I): IO[E, O] = f(i) + def toEffect: I => ZIO[Any, E, O] = i => f(i) trait ClientEndpointFactory: def umake[I, O]( diff --git a/build.sbt b/build.sbt index b4bcbd0..571c949 100644 --- a/build.sbt +++ b/build.sbt @@ -111,7 +111,7 @@ .jvmSettings( libraryDependencies += "org.apache.poi" % "poi-ooxml" % "5.2.1" ) - .dependsOn(core) + .dependsOn(core, `tapir-support`) lazy val `scenarios-ui` = project .in(file("ui/scenarios")) diff --git a/tapir/shared/src/main/scala/works/iterative/tapir/ClientEndpointFactory.scala b/tapir/shared/src/main/scala/works/iterative/tapir/ClientEndpointFactory.scala index 42ff9e1..be3e2a3 100644 --- a/tapir/shared/src/main/scala/works/iterative/tapir/ClientEndpointFactory.scala +++ b/tapir/shared/src/main/scala/works/iterative/tapir/ClientEndpointFactory.scala @@ -8,7 +8,9 @@ object Client: def apply[I, E, O](f: I => IO[E, O]): Client[I, E, O] = f - extension [I, E, O](f: Client[I, E, O]) def apply(i: I): IO[E, O] = f(i) + extension [I, E, O](f: Client[I, E, O]) + def apply(i: I): IO[E, O] = f(i) + def toEffect: I => ZIO[Any, E, O] = i => f(i) trait ClientEndpointFactory: def umake[I, O]( diff --git a/ui/js/src/main/scala/works/iterative/ui/components/ReloadableComponent.scala b/ui/js/src/main/scala/works/iterative/ui/components/ReloadableComponent.scala index f5c3fff..fed565e 100644 --- a/ui/js/src/main/scala/works/iterative/ui/components/ReloadableComponent.scala +++ b/ui/js/src/main/scala/works/iterative/ui/components/ReloadableComponent.scala @@ -1,13 +1,16 @@ package works.iterative.ui.components import com.raquo.laminar.api.L.* +import sttp.tapir.PublicEndpoint import works.iterative.core.* +import works.iterative.tapir.ClientEndpointFactory import works.iterative.ui.model.Computable import zio.* case class ReloadableComponent[A, I]( fetch: I => IO[UserMessage, A], - init: Option[I] = None + init: Option[I] = None, + loadSchedule: Schedule[Any, UserMessage, Any] = Schedule.stop )(using runtime: Runtime[Any]): private val computable: Var[Computable[A]] = Var(Computable.Uninitialized) private val memo: Var[Option[I]] = Var(init) @@ -22,14 +25,14 @@ val reload: Observer[Unit] = Observer(_ => memo.now().foreach(load)) - reload.onNext(()) + def initMod: HtmlMod = EventStream.fromValue(()) --> reload def load(input: I): Unit = computable.update(_.started) // TODO: do we need to manage the result of the run? val _ = Unsafe.unsafely { runtime.unsafe.runOrFork( - fetch(input).fold( + fetch(input).retry(loadSchedule).fold( msg => computable.update(_.fail(msg)), result => computable.update(_.update(result)) ) @@ -41,3 +44,9 @@ runtime: Runtime[Any] ): ReloadableComponent[A, Unit] = ReloadableComponent(_ => fetch, Some(())) + + def apply[A, I](endpoint: PublicEndpoint[I, Unit, A, Any]): URIO[ClientEndpointFactory, ReloadableComponent[A, I]] = + for + given Runtime[Any] <- ZIO.runtime[Any] + factory <- ZIO.service[ClientEndpointFactory] + yield new ReloadableComponent(factory.umake(endpoint).toEffect)