npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bs-socket

v1.2.2

Published

socket.io in Reason

Downloads

4

Readme

bs-socket

Simple bindings to socket.io.

To build everything run npm run build and to run the demo run npm run run and go to localhost:3000 on two tabs. You can send messages back and forth!

Documentation

Everything lives under the namespace BsSocket. To create a server/client/namespace, use Server.Make, Client.Make and Namespace.Make respectively. These functors take a module that contains 2 things: a type called clientToServer and a type called serverToClient, which define the type of the message that the client will send to the server and vice versa.

For example:

module Messages = {
  type username = string;
  type clientToServer =
  | Login(username);
  type serverToClient =
  | LoginSuccessful(username, bool);
};
module MyServer = BsSocket.Server.Make(Messages);
let io = MyServer.create();

A common pattern is to use the same message type for clientToServer and serverToClient in the following way:

module Messages = {
  type t = ...;
  type clientToServer = t;
  type serverToClient = t;
};

See example/ folder for full usage.

The API differs a bit from socket.io's API to be more idiomatic in Reason. Generally, e.g. JavaScript's socket.emit("bla", 10) becomes Server.emit(socket, Bla(10)) in Reason.

Conceptual difference between socket.io and bs-socket.io

Whereas in socket.io, emitting a message requires a string as the first argument as a way to tag what type of message you're sending, in bs-socket.io, the intended usage is that there is only one type of message and therefore there is no string tag required. This is so that the function that handles messages from the other side of the socket, i.e. MyClient.on and MyServer.on, can leverage Reason's exhaustive pattern matching on variant types, which can help ensure that they are handling all potential message variants that they could possibly be sent.

As a concrete example, the following socket.io and bs-socket.io pseudo-code would be analogous to each other.

Socket.io:

// client
socket.emit('login', { username: 'user2157' });
socket.emit('chat message', 'hello');

// server
socket.on('login', msg => ...);
socket.on('chat message', msg => ...);

Bs-socket.io:

// client
MyClient.emit(client, Login("user2157"));
MyClient.emit(client, ChatMessage("hello"));

// server
MyServer.Socket.on(socket, msg =>
  switch(msg) {
  | Login(username) => ...
  | ChatMessage(msg) => ...
  );

If you later extended the type of clientToServer to have another case, i.e.

type username = string;
type clientToServer =
  | Login(username)
  | ChatMessage(string)
  | Logout(username);

Then the previous implementation of MyServer.on would no longer compile with the reason that you haven't handled the Logout variant of the clientToServer type.

Couple Gotchas

There are a couple differences between the JS API and this one. We'll refer to the supposed module you've created from the Server.Make functor as MyServer. Same for Namespace and Client.

  • MyServer.emit is different from MyServer.Socket.emit. The former emits to all connected peers while the latter emits to the given peer.
  • Instead of io.sockets there is MyNamespace.default(io) which does the same thing.
  • Instead of io.of there is MyNamespace.of_(io) which does the same thing. (of is a Reason keyword)
  • All functions that are overloaded have different names depending on what you're passing. There's MyServer.create but also MyServer.createWithHttp (see example) among others.