SseParser v1.1.1 SseParser View Source

Server sent event parser acording to w3c using NimbleParsec ref: https://www.w3.org/TR/2009/WD-eventsource-20090421

ABNF:

  stream        = [ bom ] *event
  event         = *( comment / field ) end-of-line
  comment       = colon *any-char end-of-line
  field         = 1*name-char [ colon [ space ] *any-char ] end-of-line
  end-of-line   = ( cr lf / cr / lf / eof )
  eof           = < matches repeatedly at the end of the stream >

  ; characters
  lf            = %x000A ; U+000A LINE FEED
  cr            = %x000D ; U+000D CARRIAGE RETURN
  space         = %x0020 ; U+0020 SPACE
  colon         = %x003A ; U+003A COLON
  bom           = %xFEFF ; U+FEFF BYTE ORDER MARK
  name-char     = %x0000-0009 / %x000B-000C / %x000E-0039 / %x003B-10FFFF
                  ; a Unicode character other than U+000A LINE FEED, U+000D CARRIAGE RETURN, or U+003A COLON
  any-char      = %x0000-0009 / %x000B-000C / %x000E-10FFFF
                  ; a Unicode character other than U+000D CARRIAGE RETURN or U+003A COLON

Link to this section Summary

Functions

Parse string to sse events, returning parsed events and unparsed part of input, unparsed part can be used when next chunk from sse arrive

First feed data to parser and then interpret, see SseParser.feed/1 and SseParser.interpret/1

Interpreting parsed event stream acording to standard

Link to this section Types

Specs

comment() :: String.t()

Specs

error() ::
  {:error, String.t(), String.t(), map(), {integer(), integer()}, integer()}

Specs

event() :: [field() | comment()]
Link to this type

feed_and_interpret_success()

View Source

Specs

feed_and_interpret_success() :: {:ok, [interpreted_event()], String.t()}

Specs

feed_error() ::
  {:error, String.t(), String.t(), map(), {integer(), integer()}, integer()}

Specs

feed_success() :: {:ok, [event()], String.t()}

Specs

field() :: {String.t(), String.t() | nil}

Specs

interpreted_event() :: [
  id: String.t(),
  event: String.t(),
  data: String.t(),
  retry: integer()
]

Link to this section Functions

Specs

feed(String.t()) :: feed_success() | feed_error()

Parse string to sse events, returning parsed events and unparsed part of input, unparsed part can be used when next chunk from sse arrive

Examples

iex> SseParser.feed(":Order 3 submitted\nevent: order-submitted\nreference: order 3\n\n")
{:ok, [["Order 3 submitted", {"event", "order-submitted"}, {"reference", "order 3"}]], ""}

iex> SseParser.feed(":Test event")
{:ok, [], ":Test event"}

iex> {:ok, [], rest} = SseParser.feed(":Test event")
iex> {:ok, [], rest} = SseParser.feed(rest <> "\nname: test")
iex> SseParser.feed(rest <> "\n\n")
{:ok, [["Test event", {"name", "test"}]], ""}
Link to this function

feed_and_interpret(data)

View Source

Specs

feed_and_interpret(String.t()) :: feed_and_interpret_success() | feed_error()

First feed data to parser and then interpret, see SseParser.feed/1 and SseParser.interpret/1

Examples

iex> SseParser.feed_and_interpret(":Order 3 submitted\nevent: order-submitted\nid: 3\n\n")
{:ok, [[id: "3", event: "order-submitted"]], ""}

Specs

interpret([event()]) :: [interpreted_event()]

Interpreting parsed event stream acording to standard

  • comment is ignored
  • field id is reduced to last received value
  • field event is reduced to last received value
  • field retry is reduced to last received value that is integer
  • field data is join by newline
  • any other field is ignored

In every case, event without value {name, nil} is ignored

Examples

iex> SseParser.interpret([[{"data", "d1"}, {"data", "d2"}, {"event", "put"}, {"event", "patch"}, {"event", nil}]])
[[event: "patch", data: "d1\nd2"]]