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.

48 lines
1.4 KiB

3 years ago
  1. package outwatch.util
  2. import outwatch.helpers._
  3. // import colibri._
  4. import org.scalajs.dom.{Event, MessageEvent}
  5. import cats.effect.Sync
  6. import monix.reactive.Observable
  7. import monix.reactive.Observer
  8. import monix.execution.Cancelable
  9. import monix.reactive.OverflowStrategy
  10. import scala.concurrent.Future
  11. import monix.execution.Ack
  12. import cats.Show
  13. object MonixWS {
  14. // implicit def toObserver[F[_]: Sync, S: Show](
  15. // socket: MonixWS[F, S]
  16. // ): F[Observer[S]] = socket.sink
  17. // implicit def toObservable[F[_]: Sync, S: Show](
  18. // socket: MonixWS[F, S]
  19. // ): Observable[MessageEvent] = socket.source
  20. }
  21. class MonixWS[F[_], S](val url: String)(implicit F: Sync[F], S: Show[S]) {
  22. val ws = new org.scalajs.dom.WebSocket(url)
  23. lazy val source: Observable[MessageEvent] =
  24. Observable.create[MessageEvent](OverflowStrategy.Unbounded) { sub =>
  25. ws.onmessage = (e: MessageEvent) => sub.onNext(e)
  26. ws.onerror =
  27. (e: Event) => sub.onError(new Exception(s"Error in WebSocket: $e"))
  28. Cancelable(() => ws.close())
  29. }
  30. lazy val sink: F[Observer[S]] = {
  31. F.delay {
  32. new Observer[S] {
  33. override def onNext(elem: S): Future[Ack] = {
  34. ws.send(S.show(elem))
  35. Future.successful(Ack.Continue)
  36. }
  37. override def onError(ex: Throwable): Unit =
  38. OutwatchTracing.errorSubject.onNext(ex)
  39. override def onComplete(): Unit = ()
  40. }
  41. }
  42. }
  43. }