tapir icon indicating copy to clipboard operation
tapir copied to clipboard

[FEATURE] Scala.js Airstream WebSocket integration

Open vladimir-lu opened this issue 2 years ago • 0 comments

Tapir version: 1.9.0 Scala version: 3.3.1

Describe the bug

There are existing interpreters for ZIO and fs2 WebSocket support in the Fetch backend for Scala.js. When using Tapir with Laminar it would be nice to have Airstream integration. This issue is intended to generate some discussion about whether this integration is seen as something desirable and to iron out technical details.

How to reproduce?

Try using the Scala.js Fetch backend without ZIO/fs2 - WebSockets are not supported.

Additional information

I have actually made a first pass at an implementation in https://gist.github.com/vladimir-lu/bc6c7640eff5a1926a24371b099b2355 . There were some challenges, in particular:

  • There is no way (that I can see) to merge(run) the incoming stream with the outgoing stream in Airstream (unlike both fs2/zio), primarily because Airstream is not meant to be a generalised effect system
    • This necessitates the passing of Owner into the WebSocketToPipe[_] implementation because otherwise the first half of the pipe is never started (and could be worked around e.g. by passing the input type A as a tuple of (Owner, A) in the Pipe type definition)
  • I am still not clear on the cancellation semantics - i.e. what to do when we want to close the websocket or when it becomes closed
  • There's no equivalent of .tailRecM/.mapAccumZIO in Airstream, which also means writing some extra code to manually fuse it to the polling loop
  • Monad laws? 🙄

One other observation is that I think perhaps if the web socket implementation in sttp was extendable then you could replace the JsSimpleQueue with the corresponding airstream WriteBus and basically skip past some of the almost-surely-present unlawfulness of the example implementation above.

I think I need to convince myself (probably through using the implementation a bit longer) that this is a good idea - otherwise happy to prepare a PR.

cc @raquo

vladimir-lu avatar Nov 16 '23 18:11 vladimir-lu