Current section
Files
Jump to
Current section
Files
src/sprocket.erl
-module(sprocket).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([start/2, handle_client_message/2, shutdown/1, render/2, humanize_error/1, client_message_decoder/0, encode_runtime_message/1]).
-export_type([sprocket/0, sprocket_error/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.
-type sprocket() :: {sprocket,
gleam@erlang@process:subject(sprocket@runtime:message())}.
-type sprocket_error() :: runtime_start_error.
-file("src/sprocket.gleam", 30).
?DOC(" Starts a new Sprocket runtime with the given element and event dispatcher.\n").
-spec start(
sprocket@internal@context:element(),
fun((sprocket@runtime:runtime_message()) -> {ok, nil} | {error, nil})
) -> {ok, sprocket()} | {error, sprocket_error()}.
start(El, Dispatch) ->
case sprocket@runtime:start(El, Dispatch) of
{ok, R} ->
sprocket@runtime:render_update(R),
{ok, {sprocket, R}};
{error, _} ->
{error, runtime_start_error}
end.
-file("src/sprocket.gleam", 48).
?DOC(" Handles a client message by passing it to the runtime.\n").
-spec handle_client_message(sprocket(), sprocket@runtime:client_message()) -> nil.
handle_client_message(Spkt, Msg) ->
sprocket@runtime:handle_client_message(erlang:element(2, Spkt), Msg).
-file("src/sprocket.gleam", 53).
?DOC(" Shuts down the given Sprocket runtime.\n").
-spec shutdown(sprocket()) -> nil.
shutdown(Spkt) ->
sprocket@runtime:stop(erlang:element(2, Spkt)).
-file("src/sprocket.gleam", 58).
?DOC(" Renders the given element as a stateless element using a given renderer.\n").
-spec render(sprocket@internal@context:element(), sprocket@render:renderer(LUA)) -> LUA.
render(El, R) ->
sprocket@render:renderer(
R,
fun(Render) ->
_assert_subject = begin
_pipe = ids@cuid:start(),
gleam@result:map_error(
_pipe,
fun(Error) ->
sprocket@internal@logger:error(
<<"render.render: Failed to start a cuid channel"/utf8>>
),
Error
end
)
end,
{ok, Cuid_channel} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"sprocket"/utf8>>,
function => <<"render"/utf8>>,
line => 63})
end,
Dispatch_client_hook_event = fun(_, _, _) -> nil end,
Trigger_reconciliation = fun() -> nil end,
Update_hook = fun(_, _) -> nil end,
Ctx = sprocket@internal@context:new(
El,
Cuid_channel,
Dispatch_client_hook_event,
Trigger_reconciliation,
Update_hook
),
{reconciled_result, _, Reconciled} = sprocket@internal@reconcilers@recursive:reconcile(
Ctx,
El,
none,
none
),
Render(Reconciled)
end
).
-file("src/sprocket.gleam", 90).
?DOC(" Returns a human-readable error message for the given SprocketError.\n").
-spec humanize_error(sprocket_error()) -> binary().
humanize_error(Error) ->
case Error of
runtime_start_error ->
<<"Failed to start runtime"/utf8>>
end.
-file("src/sprocket.gleam", 107).
?DOC(" Decoder for inbound client hook events.\n").
-spec inbound_client_hook_event_decoder() -> gleam@dynamic@decode:decoder(sprocket@runtime:client_message()).
inbound_client_hook_event_decoder() ->
gleam@dynamic@decode:field(
<<"id"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Element_id) ->
gleam@dynamic@decode:field(
<<"hook"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Hook) ->
gleam@dynamic@decode:field(
<<"kind"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Kind) ->
gleam@dynamic@decode:optional_field(
<<"payload"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_dynamic/1}
),
fun(Payload) ->
gleam@dynamic@decode:success(
{inbound_client_hook_event,
Element_id,
Hook,
Kind,
Payload}
)
end
)
end
)
end
)
end
).
-file("src/sprocket.gleam", 120).
-spec client_event_decoder() -> gleam@dynamic@decode:decoder(sprocket@runtime:client_message()).
client_event_decoder() ->
gleam@dynamic@decode:field(
<<"id"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Element_id) ->
gleam@dynamic@decode:field(
<<"kind"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Kind) ->
gleam@dynamic@decode:optional_field(
<<"payload"/utf8>>,
gleam_stdlib:identity(nil),
{decoder, fun gleam@dynamic@decode:decode_dynamic/1},
fun(Payload) ->
gleam@dynamic@decode:success(
{client_event, Element_id, Kind, Payload}
)
end
)
end
)
end
).
-file("src/sprocket.gleam", 97).
?DOC(" Decoder for client messages.\n").
-spec client_message_decoder() -> gleam@dynamic@decode:decoder(sprocket@runtime:client_message()).
client_message_decoder() ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:at(
[0],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
fun(Message_type) -> case Message_type of
<<"hook"/utf8>> ->
gleam@dynamic@decode:at(
[1],
inbound_client_hook_event_decoder()
);
_ ->
gleam@dynamic@decode:at([1], client_event_decoder())
end end
).
-file("src/sprocket.gleam", 176).
-spec payload_decoder() -> gleam@dynamic@decode:decoder(gleam@json:json()).
payload_decoder() ->
gleam@dynamic@decode:recursive(
fun() ->
gleam@dynamic@decode:one_of(
begin
_pipe = {decoder, fun gleam@dynamic@decode:decode_string/1},
gleam@dynamic@decode:map(_pipe, fun gleam@json:string/1)
end,
[begin
_pipe@1 = {decoder,
fun gleam@dynamic@decode:decode_int/1},
gleam@dynamic@decode:map(_pipe@1, fun gleam@json:int/1)
end,
begin
_pipe@2 = {decoder,
fun gleam@dynamic@decode:decode_float/1},
gleam@dynamic@decode:map(
_pipe@2,
fun gleam@json:float/1
)
end,
begin
_pipe@3 = {decoder,
fun gleam@dynamic@decode:decode_bool/1},
gleam@dynamic@decode:map(_pipe@3, fun gleam@json:bool/1)
end,
begin
_pipe@4 = gleam@dynamic@decode:list(payload_decoder()),
gleam@dynamic@decode:map(
_pipe@4,
fun gleam@json:preprocessed_array/1
)
end,
begin
_pipe@5 = gleam@dynamic@decode:dict(
{decoder, fun gleam@dynamic@decode:decode_string/1},
payload_decoder()
),
gleam@dynamic@decode:map(_pipe@5, fun(D) -> _pipe@6 = D,
_pipe@7 = maps:to_list(_pipe@6),
gleam@json:object(_pipe@7) end)
end]
)
end
).
-file("src/sprocket.gleam", 172).
-spec encode_payload(gleam@dynamic:dynamic_()) -> {ok, gleam@json:json()} |
{error, list(gleam@dynamic@decode:decode_error())}.
encode_payload(Payload) ->
gleam@dynamic@decode:run(Payload, payload_decoder()).
-file("src/sprocket.gleam", 133).
?DOC(" Encodes a runtime message as JSON.\n").
-spec encode_runtime_message(sprocket@runtime:runtime_message()) -> gleam@json:json().
encode_runtime_message(Event) ->
case Event of
{full_update, Update} ->
sprocket@render:renderer(
sprocket@renderers@json:json_renderer(),
fun(Render_json) ->
gleam@json:preprocessed_array(
[gleam@json:string(<<"ok"/utf8>>), Render_json(Update)]
)
end
);
{patch_update, P} ->
gleam@json:preprocessed_array(
[gleam@json:string(<<"update"/utf8>>),
sprocket@internal@patch:patch_to_json(P)]
);
{outbound_client_hook_event, Id, Hook, Kind, Payload} ->
Payload_json = begin
_pipe = Payload,
_pipe@1 = gleam@option:map(_pipe, fun encode_payload/1),
_pipe@2 = gleam@option:map(
_pipe@1,
fun gleam@option:from_result/1
),
gleam@option:flatten(_pipe@2)
end,
gleam@json:preprocessed_array(
[gleam@json:string(<<"hook"/utf8>>), case Payload_json of
{some, Payload_json@1} ->
gleam@json:object(
[{<<"id"/utf8>>, gleam@json:string(Id)},
{<<"hook"/utf8>>, gleam@json:string(Hook)},
{<<"kind"/utf8>>, gleam@json:string(Kind)},
{<<"payload"/utf8>>, Payload_json@1}]
);
none ->
gleam@json:object(
[{<<"id"/utf8>>, gleam@json:string(Id)},
{<<"hook"/utf8>>, gleam@json:string(Hook)},
{<<"kind"/utf8>>, gleam@json:string(Kind)}]
)
end]
)
end.