Current section
Files
Jump to
Current section
Files
src/sprocket@internal@context.erl
-module(sprocket@internal@context).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([has_id/2, compare_deps/2, new/5, prepare_for_reconciliation/1, fetch_or_init_hook/2, update_hook/3, push_event_handler/2, get_event_handler/2, push_client_hook/2, get_client_hook/3, dispatch_client_hook_event/4]).
-export_type([element_id/0, event_handler/0, client_hook_id/0, attribute/0, element/0, effect_result/0, callback_result/0, memo_result/0, hook_id/0, hook/0, compared/1, component_wip/0, context/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(false).
-type element_id() :: any().
-type event_handler() :: {event_handler,
sprocket@internal@utils@unique:unique(element_id()),
binary(),
fun((gleam@dynamic:dynamic_()) -> nil)}.
-type client_hook_id() :: {client_hook_id,
sprocket@internal@utils@unique:unique(element_id()),
binary(),
sprocket@internal@utils@unique:unique(hook_id())}.
-type attribute() :: {attribute, binary(), gleam@dynamic:dynamic_()} |
{event, binary(), fun((gleam@dynamic:dynamic_()) -> nil)} |
{client_hook, sprocket@internal@utils@unique:unique(hook_id()), binary()}.
-type element() :: {element, binary(), list(attribute()), list(element())} |
{component,
fun((context(), gleam@dynamic:dynamic_()) -> {context(), element()}),
gleam@dynamic:dynamic_()} |
{fragment, list(element())} |
{debug, binary(), gleam@option:option(gleam@dynamic:dynamic_()), element()} |
{keyed, binary(), element()} |
{ignore_update, element()} |
{provider, binary(), gleam@dynamic:dynamic_(), element()} |
{text, binary()} |
{custom, binary(), binary()}.
-type effect_result() :: {effect_result,
gleam@option:option(fun(() -> nil)),
gleam@option:option(list(gleam@dynamic:dynamic_()))}.
-type callback_result() :: {callback_result,
gleam@option:option(list(gleam@dynamic:dynamic_()))}.
-type memo_result() :: {memo_result,
gleam@option:option(list(gleam@dynamic:dynamic_()))}.
-type hook_id() :: any().
-type hook() :: {callback,
sprocket@internal@utils@unique:unique(hook_id()),
fun(() -> nil),
gleam@option:option(callback_result())} |
{memo,
sprocket@internal@utils@unique:unique(hook_id()),
gleam@dynamic:dynamic_(),
gleam@option:option(memo_result())} |
{effect,
sprocket@internal@utils@unique:unique(hook_id()),
fun(() -> gleam@option:option(fun(() -> nil))),
list(gleam@dynamic:dynamic_()),
gleam@option:option(effect_result())} |
{reducer,
sprocket@internal@utils@unique:unique(hook_id()),
gleam@dynamic:dynamic_(),
fun(() -> nil)} |
{state,
sprocket@internal@utils@unique:unique(hook_id()),
gleam@dynamic:dynamic_()} |
{client,
sprocket@internal@utils@unique:unique(hook_id()),
binary(),
gleam@option:option(fun((binary(), gleam@option:option(gleam@dynamic:dynamic_()), fun((binary(), gleam@option:option(gleam@dynamic:dynamic_())) -> nil)) -> nil))}.
-type compared(JXI) :: {changed, JXI} | unchanged.
-type component_wip() :: {component_wip,
sprocket@internal@utils@ordered_map:ordered_map(integer(), hook()),
integer(),
boolean()}.
-type context() :: {context,
element(),
component_wip(),
list(event_handler()),
list(client_hook_id()),
fun(() -> nil),
fun((sprocket@internal@utils@unique:unique(hook_id()), fun((hook()) -> hook())) -> nil),
fun((sprocket@internal@utils@unique:unique(hook_id()), binary(), gleam@option:option(gleam@dynamic:dynamic_())) -> nil),
gleam@erlang@process:subject(ids@cuid:message()),
gleam@dict:dict(binary(), gleam@dynamic:dynamic_())}.
-file("src/sprocket/internal/context.gleam", 112).
?DOC(false).
-spec has_id(hook(), sprocket@internal@utils@unique:unique(hook_id())) -> boolean().
has_id(Hook, Hook_id) ->
case Hook of
{callback, Id, _, _} when Id =:= Hook_id ->
true;
{memo, Id@1, _, _} when Id@1 =:= Hook_id ->
true;
{effect, Id@2, _, _, _} when Id@2 =:= Hook_id ->
true;
{state, Id@3, _} when Id@3 =:= Hook_id ->
true;
{client, Id@4, _, _} when Id@4 =:= Hook_id ->
true;
_ ->
false
end.
-file("src/sprocket/internal/context.gleam", 128).
?DOC(false).
-spec compare_deps(
list(gleam@dynamic:dynamic_()),
list(gleam@dynamic:dynamic_())
) -> compared(list(gleam@dynamic:dynamic_())).
compare_deps(Prev_deps, Deps) ->
case gleam@list:strict_zip(Prev_deps, Deps) of
{error, _} ->
sprocket@internal@exceptions:throw_on_unexpected_deps_mismatch(
{<<"compare_deps"/utf8>>, Prev_deps, Deps}
);
{ok, Zipped_deps} ->
case gleam@list:all(
Zipped_deps,
fun(Z) ->
{A, B} = Z,
A =:= B
end
) of
true ->
unchanged;
_ ->
{changed, Deps}
end
end.
-file("src/sprocket/internal/context.gleam", 171).
?DOC(false).
-spec new(
element(),
gleam@erlang@process:subject(ids@cuid:message()),
fun((sprocket@internal@utils@unique:unique(hook_id()), binary(), gleam@option:option(gleam@dynamic:dynamic_())) -> nil),
fun(() -> nil),
fun((sprocket@internal@utils@unique:unique(hook_id()), fun((hook()) -> hook())) -> nil)
) -> context().
new(
El,
Cuid_channel,
Dispatch_client_hook_event,
Trigger_reconciliation,
Update_hook
) ->
{context,
El,
{component_wip, sprocket@internal@utils@ordered_map:new(), 0, true},
[],
[],
Trigger_reconciliation,
Update_hook,
Dispatch_client_hook_event,
Cuid_channel,
maps:new()}.
-file("src/sprocket/internal/context.gleam", 191).
?DOC(false).
-spec prepare_for_reconciliation(context()) -> context().
prepare_for_reconciliation(Ctx) ->
_record = Ctx,
{context,
erlang:element(2, _record),
erlang:element(3, _record),
[],
[],
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record),
erlang:element(9, _record),
erlang:element(10, _record)}.
-file("src/sprocket/internal/context.gleam", 195).
?DOC(false).
-spec fetch_or_init_hook(context(), fun(() -> hook())) -> {context(),
hook(),
integer()}.
fetch_or_init_hook(Ctx, Init) ->
Index = erlang:element(3, erlang:element(3, Ctx)),
Hooks = erlang:element(2, erlang:element(3, Ctx)),
case sprocket@internal@utils@ordered_map:get(Hooks, Index) of
{ok, Hook} ->
{begin
_record = Ctx,
{context,
erlang:element(2, _record),
begin
_record@1 = erlang:element(3, Ctx),
{component_wip,
erlang:element(2, _record@1),
Index + 1,
erlang:element(4, _record@1)}
end,
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record),
erlang:element(9, _record),
erlang:element(10, _record)}
end,
Hook,
Index};
{error, nil} ->
case erlang:element(4, erlang:element(3, Ctx)) of
true ->
nil;
false ->
sprocket@internal@logger:error(
<<<<"
Hook not found for index: "/utf8,
(erlang:integer_to_binary(Index))/binary>>/binary,
". This indicates a hook was dynamically
created since first render which is not allowed.
"/utf8>>
),
erlang:error(#{gleam_error => panic,
message => <<"`panic` expression evaluated."/utf8>>,
module => <<"sprocket/internal/context"/utf8>>,
function => <<"fetch_or_init_hook"/utf8>>,
line => 222})
end,
Hook@1 = Init(),
{begin
_record@2 = Ctx,
{context,
erlang:element(2, _record@2),
{component_wip,
sprocket@internal@utils@ordered_map:insert(
erlang:element(2, erlang:element(3, Ctx)),
Index,
Hook@1
),
Index + 1,
erlang:element(4, erlang:element(3, Ctx))},
erlang:element(4, _record@2),
erlang:element(5, _record@2),
erlang:element(6, _record@2),
erlang:element(7, _record@2),
erlang:element(8, _record@2),
erlang:element(9, _record@2),
erlang:element(10, _record@2)}
end,
Hook@1,
Index}
end.
-file("src/sprocket/internal/context.gleam", 245).
?DOC(false).
-spec update_hook(context(), hook(), integer()) -> context().
update_hook(Ctx, Hook, Index) ->
_record = Ctx,
{context,
erlang:element(2, _record),
begin
_record@1 = erlang:element(3, Ctx),
{component_wip,
sprocket@internal@utils@ordered_map:update(
erlang:element(2, erlang:element(3, Ctx)),
Index,
Hook
),
erlang:element(3, _record@1),
erlang:element(4, _record@1)}
end,
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record),
erlang:element(9, _record),
erlang:element(10, _record)}.
-file("src/sprocket/internal/context.gleam", 255).
?DOC(false).
-spec push_event_handler(context(), event_handler()) -> context().
push_event_handler(Ctx, Handler) ->
_record = Ctx,
{context,
erlang:element(2, _record),
erlang:element(3, _record),
[Handler | erlang:element(4, Ctx)],
erlang:element(5, _record),
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record),
erlang:element(9, _record),
erlang:element(10, _record)}.
-file("src/sprocket/internal/context.gleam", 259).
?DOC(false).
-spec get_event_handler(
context(),
sprocket@internal@utils@unique:unique(element_id())
) -> {context(), {ok, event_handler()} | {error, nil}}.
get_event_handler(Ctx, Id) ->
Handler = gleam@list:find(
erlang:element(4, Ctx),
fun(H) ->
{event_handler, I, _, _} = H,
I =:= Id
end
),
{Ctx, Handler}.
-file("src/sprocket/internal/context.gleam", 272).
?DOC(false).
-spec push_client_hook(context(), client_hook_id()) -> context().
push_client_hook(Ctx, Hook) ->
_record = Ctx,
{context,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
[Hook | erlang:element(5, Ctx)],
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record),
erlang:element(9, _record),
erlang:element(10, _record)}.
-file("src/sprocket/internal/context.gleam", 276).
?DOC(false).
-spec get_client_hook(
context(),
sprocket@internal@utils@unique:unique(element_id()),
binary()
) -> {context(), {ok, client_hook_id()} | {error, nil}}.
get_client_hook(Ctx, Id, Name) ->
Hook = gleam@list:find(
erlang:element(5, Ctx),
fun(H) ->
{client_hook_id, I, N, _} = H,
(I =:= Id) andalso (N =:= Name)
end
),
{Ctx, Hook}.
-file("src/sprocket/internal/context.gleam", 290).
?DOC(false).
-spec dispatch_client_hook_event(
context(),
sprocket@internal@utils@unique:unique(hook_id()),
binary(),
gleam@option:option(gleam@dynamic:dynamic_())
) -> nil.
dispatch_client_hook_event(Ctx, Id, Kind, Payload) ->
(erlang:element(8, Ctx))(Id, Kind, Payload).