Current section

Files

Jump to
ssevents src ssevents@event.erl
Raw

src/ssevents@event.erl

-module(ssevents@event).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/ssevents/event.gleam").
-export([new/1, message/1, event/2, named/2, id/2, from_parts/4, retry/2, data/2, name_of/1, data_of/1, id_of/1, retry_of/1, event_item/1]).
-export_type([event/0, item/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Event and item domain values.\n"
"\n"
" `Event` is opaque so the package can evolve its representation\n"
" without a breaking change. Construct via `new`, `from_parts`, and\n"
" the builder helpers. `Item` stays transparent because callers and\n"
" helper modules frequently pattern match on whether a stream element\n"
" is an event or a comment.\n"
).
-opaque event() :: {event,
gleam@option:option(binary()),
binary(),
gleam@option:option(binary()),
gleam@option:option(integer())}.
-type item() :: {event_item, event()} | {comment, binary()}.
-file("src/ssevents/event.gleam", 26).
-spec new(binary()) -> event().
new(Data) ->
{event, none, Data, none, none}.
-file("src/ssevents/event.gleam", 44).
-spec message(binary()) -> event().
message(Data) ->
new(Data).
-file("src/ssevents/event.gleam", 84).
?DOC(
" Strip CR (U+000D), LF (U+000A), and NUL (U+0000) from `value`.\n"
"\n"
" CR / LF inside an `event` or `id` value cannot survive the SSE wire\n"
" format — both are line terminators per WHATWG SSE §9.2.5, so a\n"
" literal CR / LF inside the value would split the field across two\n"
" lines on encode and the decoder would parse the post-LF tail as an\n"
" unrelated unknown field. NUL inside `id` is ignored by the decoder\n"
" per §9.2.6, breaking round-trip.\n"
"\n"
" Stripping silently at construction time is the same posture\n"
" `multipartkit/form.add_field` takes for the analogous header-injection\n"
" risk: it keeps `from_parts`, `event/2`, and `id/2` infallible while\n"
" guaranteeing that `decode(encode(x))` round-trips for any caller-built\n"
" `Event`.\n"
).
-spec sanitize_field_value(binary()) -> binary().
sanitize_field_value(Value) ->
_pipe = Value,
_pipe@1 = gleam@string:replace(_pipe, <<"\r\n"/utf8>>, <<""/utf8>>),
_pipe@2 = gleam@string:replace(_pipe@1, <<"\r"/utf8>>, <<""/utf8>>),
_pipe@3 = gleam@string:replace(_pipe@2, <<"\n"/utf8>>, <<""/utf8>>),
gleam@string:replace(_pipe@3, <<"\x{0000}"/utf8>>, <<""/utf8>>).
-file("src/ssevents/event.gleam", 52).
-spec event(event(), binary()) -> event().
event(Event, Name) ->
{event,
{some, sanitize_field_value(Name)},
erlang:element(3, Event),
erlang:element(4, Event),
erlang:element(5, Event)}.
-file("src/ssevents/event.gleam", 48).
-spec named(binary(), binary()) -> event().
named(Name, Data) ->
_pipe = new(Data),
event(_pipe, Name).
-file("src/ssevents/event.gleam", 61).
-spec id(event(), binary()) -> event().
id(Event, Id) ->
{event,
erlang:element(2, Event),
erlang:element(3, Event),
{some, sanitize_field_value(Id)},
erlang:element(5, Event)}.
-file("src/ssevents/event.gleam", 92).
-spec option_sanitize(gleam@option:option(binary())) -> gleam@option:option(binary()).
option_sanitize(Opt) ->
case Opt of
none ->
none;
{some, Value} ->
{some, sanitize_field_value(Value)}
end.
-file("src/ssevents/event.gleam", 30).
-spec from_parts(
gleam@option:option(binary()),
binary(),
gleam@option:option(binary()),
gleam@option:option(integer())
) -> event().
from_parts(Event_name, Data, Id, Retry) ->
{event, option_sanitize(Event_name), Data, option_sanitize(Id), Retry}.
-file("src/ssevents/event.gleam", 99).
-spec retry(event(), integer()) -> event().
retry(Event, Milliseconds) ->
{event,
erlang:element(2, Event),
erlang:element(3, Event),
erlang:element(4, Event),
{some, Milliseconds}}.
-file("src/ssevents/event.gleam", 108).
-spec data(event(), binary()) -> event().
data(Event, Data) ->
{event,
erlang:element(2, Event),
Data,
erlang:element(4, Event),
erlang:element(5, Event)}.
-file("src/ssevents/event.gleam", 112).
-spec name_of(event()) -> gleam@option:option(binary()).
name_of(Event) ->
erlang:element(2, Event).
-file("src/ssevents/event.gleam", 116).
-spec data_of(event()) -> binary().
data_of(Event) ->
erlang:element(3, Event).
-file("src/ssevents/event.gleam", 120).
-spec id_of(event()) -> gleam@option:option(binary()).
id_of(Event) ->
erlang:element(4, Event).
-file("src/ssevents/event.gleam", 124).
-spec retry_of(event()) -> gleam@option:option(integer()).
retry_of(Event) ->
erlang:element(5, Event).
-file("src/ssevents/event.gleam", 128).
-spec event_item(event()) -> item().
event_item(Event) ->
{event_item, Event}.