All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.cheleb.ziolaminartapir.ZJS.scala Maven / Gradle / Ivy

package dev.cheleb.ziolaminartapir

import zio.*

import scala.annotation.targetName

import com.raquo.laminar.api.L.*
import sttp.tapir.Endpoint
import dev.cheleb.ziojwt.WithToken

/** ZIO JS extension methods.
  *
  * This object contains:
  *   - convenience methods for calling endpoints.
  *   - extension methods for ZIO that are specific to the Laminar JS
  *     environment.
  */
object ZJS {

  /** Extension to ZIO[BakendClient, E, A] that allows us to run in JS.
    *
    * This is a side effect, and should be used with caution.
    */
  extension [E <: Throwable, A](zio: ZIO[BackendClient, E, A])
    /** Emit the result of the ZIO to an EventBus.
      *
      * @param bus
      */
    def emitTo(
        bus: EventBus[A]
    ): Unit =
      Unsafe.unsafe { implicit unsafe =>
        Runtime.default.unsafe.fork(
          zio
            .tapError(e => Console.printLineError(e.getMessage()))
            .tap(a => ZIO.attempt(bus.emit(a)))
            .provide(BackendClientLive.configuredLayer("http://localhost:8080"))
        )
      }

    /** Run the ZIO in JS.
      *
      * @return
      */
    def runJs: Unit =
      Unsafe.unsafe { implicit unsafe =>
        Runtime.default.unsafe.fork(
          zio
            .tapError(e => Console.printLineError(e.getMessage()))
            .provide(
              BackendClientLive.configuredLayer("http://localhost:8080")
            )
        )
      }

    /** Emit the result of the ZIO to an EventBus, and return the EventStream.
      *
      * @return
      */
    def toEventStream(using
        session: Session[WithToken]
    ): EventStream[A] =
      val eventBus = EventBus[A]()
      emitTo(eventBus)
      eventBus.events

  /** Extension that allows us to turn an unsecure endpoint to a function from a
    * payload to a ZIO.
    */
  extension [I, E <: Throwable, O](endpoint: Endpoint[Unit, I, E, O, Any])
    /** Call the endpoint with a payload, and get a ZIO back.
      * @param payload
      * @return
      */
    def apply(payload: I): RIO[BackendClient, O] =
      ZIO
        .service[BackendClient]
        .flatMap(_.endpointRequestZIO(endpoint)(payload))

  /** Extension that allows us to turn a secured endpoint to a function from a
    * payload to a ZIO.
    */
  extension [I, E <: Throwable, O](endpoint: Endpoint[String, I, E, O, Any])
    /** Call the secured endpoint with a payload, and get a ZIO back.
      * @param payload
      * @return
      */
    @targetName("securedApply")
    def apply[UserToken <: WithToken](
        payload: I
    )(using session: Session[UserToken]): RIO[BackendClient, O] =
      ZIO
        .service[BackendClient]
        .flatMap(_.securedEndpointRequestZIO(endpoint)(payload))

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy