You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
49 lines
1.4 KiB
49 lines
1.4 KiB
package outwatch.util
|
|
|
|
import scala.concurrent.Future
|
|
|
|
import cats.Show
|
|
import cats.effect.Sync
|
|
import monix.execution.Ack
|
|
import monix.execution.Cancelable
|
|
import monix.reactive.Observable
|
|
import monix.reactive.Observer
|
|
import monix.reactive.OverflowStrategy
|
|
import org.scalajs.dom.Event
|
|
import org.scalajs.dom.MessageEvent
|
|
import outwatch.helpers._
|
|
|
|
object MonixWS {
|
|
// implicit def toObserver[F[_]: Sync, S: Show](
|
|
// socket: MonixWS[F, S]
|
|
// ): F[Observer[S]] = socket.sink
|
|
// implicit def toObservable[F[_]: Sync, S: Show](
|
|
// socket: MonixWS[F, S]
|
|
// ): Observable[MessageEvent] = socket.source
|
|
}
|
|
|
|
class MonixWS[F[_], S](val url: String)(implicit F: Sync[F], S: Show[S]) {
|
|
val ws = new org.scalajs.dom.WebSocket(url)
|
|
|
|
val source: Observable[MessageEvent] =
|
|
Observable.create[MessageEvent](OverflowStrategy.Unbounded) { sub =>
|
|
ws.onmessage = (e: MessageEvent) => sub.onNext(e)
|
|
ws.onerror =
|
|
(e: Event) => sub.onError(new Exception(s"Error in WebSocket: $e"))
|
|
Cancelable(() => ws.close())
|
|
}
|
|
|
|
val sink: F[Observer[S]] = {
|
|
F.delay {
|
|
new Observer[S] {
|
|
override def onNext(elem: S): Future[Ack] = {
|
|
ws.send(S.show(elem))
|
|
Future.successful(Ack.Continue)
|
|
}
|
|
override def onError(ex: Throwable): Unit =
|
|
OutwatchTracing.errorSubject.onNext(ex)
|
|
override def onComplete(): Unit = ()
|
|
}
|
|
}
|
|
}
|
|
}
|