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

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package outwatch.util
  2. import scala.concurrent.Future
  3. import cats.Show
  4. import cats.effect.Sync
  5. import monix.execution.Ack
  6. import monix.execution.Cancelable
  7. import monix.reactive.Observable
  8. import monix.reactive.Observer
  9. import monix.reactive.OverflowStrategy
  10. import org.scalajs.dom.Event
  11. import org.scalajs.dom.MessageEvent
  12. import outwatch.helpers._
  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. 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. 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. }