Support for simple serialization to more generally useful type
aarondl opened this issue · comments
I was working with this library in order to implement bidirectional communication over grpc-web using a new elm protocol buffer library that makes use of this.
In order to get the bytes that the elm-protocol-buffers library created to the javascript library I used a port. But I found that taking this type from Elm to the outside world was sort of difficult.
In the end I used loop
and unsignedUint8
to change it from Bytes.Bytes
to List Int
so I could throw it through the port at which point I had some thoughts:
- Given the state of Elm 0.19 with respect to kernel code in order to support more complicated protocols (grpc) the bytes type will almost certainly need to be given to a port so maybe it should become one of the natively supported pass-through types listed here: https://guide.elm-lang.org/interop/flags.html
- Even if the above is done it's probably still required to be able to serialize this to JSON easily. Though I understand that JSON has no native bytes representation so we'd have to pick our poison to solve that.
- In lieu of the above two options maybe just a built-in way to marshal between List Int and the Bytes type?
Appreciate any thoughts on this issue.
I too hit this wall when I was sending Protobuf messages over WebSockets. I resorted to the same hack of coercing to a List Int
and then sending across the port. I can't speak to the performance implications but something about having to await
a binary ArrayBuffer
to then turn into a Uint8Array
and THEN finally map to a plain-Jane JS list feels very very wrong and do lots of needless work:
// On the receiving side in JS
var ws = new WebSocket("ws://host.site/path/to/websocket");
ws.onmessage = function(event) {
event.arrayBuffer().then(buf => {
let intList = [];
for (let val of buf) {
intList.push(val)
}
app.ports.ws.send(intList);
});
}
Yuck!
I stopped by to say though that I think this issue of the Bytes
object being so opaque and therefore cumbersome feels more like a symptom of a problem than an actual problem. What I am getting at is this: take the elm/http
package. It has no issue whatsoever in dealing with binary request and response bodies. Yet there isn't even native support for WebSockets in Elm at all!
Really it's a bit silly when you think about it. Elm, a language that targets the Internet and works towards being a JS replacement, natively (or at least transparently) supports HTTP but not WebSockets? That seems like an almost-intentional shot to the foot.
I exaggerate of course. 😄 Understandably, Elm has it's priorities and WebSockets requiring some JS hackery is a minor transgression. Perfectly reasonable 👍
Overall I am fantastically impressed everything in the ecosystem. I thought it worth noting however that if Elm's support for WebSockets were better, then this conversation wouldn't be happening in the first place. Let's solve X instead of Y!