Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2 API proposal #14

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

V2 API proposal #14

wants to merge 1 commit into from

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.

2 participants