softwaremill / softwaremill/tapir
[FEATURE] Scala.js Airstream WebSocket integration
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 1.5k
- Forks
- 468
- Avg merge
- 5h 37m
- Merged PRs (30d)
- 34
Description
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
Ownerinto theWebSocketToPipe[_]implementation because otherwise the first half of the pipe is never started (and could be worked around e.g. by passing the input typeAas a tuple of(Owner, A)in thePipetype definition)
- This necessitates the passing of
- 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/.mapAccumZIOin 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
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the existing ZIO and fs2 WebSocket interpreters in the Scala.js Fetch backend, then review the proposed WebSocketToPipe implementation and linked gist. Resolve the Airstream ownership, cancellation, stream-fusion, and lawfulness questions before defining the integration; done means an agreed design or a working, validated Airstream WebSocket integration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- api, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100