package outwatch.util import cats.effect.Sync import colibri._ import org.scalajs.dom.Event import org.scalajs.dom.MessageEvent import outwatch.helpers._ object WebSocketF { implicit def toObserver[F[_]: Sync]( socket: WebSocketF[F] ): F[Observer[String]] = socket.sink implicit def toObservable[F[_]: Sync]( socket: WebSocketF[F] ): Observable[MessageEvent] = socket.source } class WebSocketF[F[_]](val url: String)(implicit F: Sync[F]) { val ws = new org.scalajs.dom.WebSocket(url) val source: Observable[MessageEvent] = Observable.create[MessageEvent] { observer => ws.onmessage = (e: MessageEvent) => observer.onNext(e) ws.onerror = (e: Event) => observer.onError(new Exception(s"Error in WebSocket: $e")) Cancelable(() => ws.close()) } val sink: F[Observer[String]] = { F.delay { new Observer[String] { override def onNext(elem: String): Unit = ws.send(elem) override def onError(ex: Throwable): Unit = OutwatchTracing.errorSubject.onNext(ex) } } } }