-module(sprocket@internal@context). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([component/2, 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@dynamic:dynamic_(), fun((binary(), gleam@option:option(gleam@dynamic:dynamic_())) -> nil)) -> nil))}. -type compared(JXN) :: {changed, JXN} | 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", 53). ?DOC(false). -spec component(fun((context(), JXZ) -> {context(), element()}), JXZ) -> element(). component(C, Props) -> Component = begin _pipe = C, _pipe@1 = gleam_stdlib:identity(_pipe), sprocket@internal@utils@unsafe_coerce:unsafe_coerce(_pipe@1) end, Props@1 = begin _pipe@2 = Props, gleam_stdlib:identity(_pipe@2) end, {component, Component, Props@1}. -file("src/sprocket/internal/context.gleam", 127). ?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", 143). ?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", 186). ?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", 206). ?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", 210). ?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 => 237}) 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", 260). ?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", 270). ?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", 274). ?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", 287). ?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", 291). ?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", 305). ?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).