sigmal

Package Version Hex Docs

This is a dead simple signals library for the JavaScript target. It allows long-running processes to communicate. I made it to use on a web server, but it can be used in just about any application.

Example

Here is a minimal example with smol. Every time a request is made to the say path, the server emits say SSE events on the listen path.

pub fn main() {
  let signal = signal.new()
  smol.new(handler(_, signal))
  |> smol.start
}

pub fn handler(request, signal) {
  case request.path_segments(request) {
    ["say", msg] -> {
      signal.send(signal, msg)
      smol.send_status(200)
    }
    ["listen"] ->
      smol.server_sent_events(Nil, fn(_) {
        use msg <- promise.await(signal.receive(signal))
        smol.send(Nil, smol.SseEvent(Some("say"), msg, None, None))
      })
    _ -> smol.send_status(404)
  }
  |> promise.resolve
}

Usage

Always begin by creating your Signals. They must be shared in order for communication to work. There is no way to name a Signal or find one by name.

Signals are generic over the type of messages they transfer. This means that one Signal can only deliver one type of message, even across different topics. If you need to listen for multiple types of messages, you can either use multiple Signals (which is problematic because you can only await a receive call on one of them at a time), or write a wrapper type:

type Msg1 {
  Msg1(..)
}

type Msg2 {
  Msg2(..)
}

type MsgWrapper {
  Msg1Wrapper(Msg1)
  Msg2Wrapper(Msg2)
}

// inside a function
  use msg <- promise.await(signal.receive(my_signal))
  case msg {
    Msg1Wrapper(_) -> ..
    Msg2Wrapper(_) -> ..
  }

receive_* calls are resolved immediately after a send_* call is made to the corresponding topic(s). Messages are not stored or queued, i.e. if a message is not received, it is lost forever. This means that in order for a message to be delivered successfully, receive_* must be called before send_*.

There is no way to subscribe to messages from a signal / topic. However, you should be able to replicate this functionality with a recursive async function that repeatedly calls receive_*.

Notes

Please remember that this is a “dead simple” library. I do not intend to add any more complex functionality to it. However, please do feel free to use my code as a base for writing your own.

I have done very little testing with this library. Bug reports are welcome.

Search Document