Skip to content

Conversation

@bsansouci
Copy link
Collaborator

Thanks @ryyppy and @peterpme for bringing this to my attention :)

This proposal should make the bindings a bit thinner, by removing the functors, while staying convenient by allowing the user to send reason data structures back and forth thanks to our serializer.

let socket = Client.create();
socket->Socket.emit("login", SharedTypes.Hi);
socket->Socket.on("message", (. x) =>
  switch (x) {
  | SharedTypes.Message(Data(s)) => Js.log("data!")
  | SharedTypes.Message(OrOthers) => Js.log("OrOthers")
  | SharedTypes.MessageOnEnter(s) => Js.log("User pressed enter")
  }
);

These bindings are now unsafe, as you can send any data with any event and nothing checks that you're going to receive the right data. I think that's pretty bad, as it effectively removes the utility of types (if you cannot trust them). I would like to fix before we ship.

One simple way would be to make the emit/on functions not have the type signature external emit: (socket, 'a, string) => unit = "emit" but something like let emit: (socket, 'a) => unit. This means the first time you call emit you restrict the type of the potential payloads to a single one, which means that type probably should take the shape:

type payload = 
  | Message(messageT)
  | Login(loginT)
  | SomeOtherThing(thingT)

It dramatically simplifies the API and brings type safety back.

An alternative would be to use GADTs, but those are no better than functors in terms of difficulty to teach.

Unrelatedly, I think writing serializers / deserializers is a huge time sink and luckily unnecessary here, as we can write a generalized one.

@peterpme
Copy link

Hey @bsansouci thanks so much for putting this together 😍

My preliminary questions:

  • What's left to cut a new release that supports socket 2.3.0?
  • I see Socket.on("message") -> does this mean that we will be forced to use message and then handle the type checking inside the callback with that generic argument?
  • If I'm not using bs-socket on the server, will this approach still work (i think its worth pointing out in the README)
  • Lastly, I know this approach is different than what @ryyppy. What makes this better?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants