-module(mochi@dataloader). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/mochi/dataloader.gleam"). -export([default_options/0, new_with_options/2, new/1, clear_cache/1, clear_key/2, prime/3, prime_error/3, load/2, load_many/2, int_loader/1, string_loader/1, int_batch_loader/1, string_batch_loader/1, int_loader_result/3, string_loader_result/3, int_key/1, string_key/1]). -export_type([data_loader_options/0, data_loader_state/2, data_loader/2]). -type data_loader_options() :: {data_loader_options, integer(), boolean()}. -type data_loader_state(EDV, EDW) :: {data_loader_state, fun((list(EDV)) -> {ok, list({ok, EDW} | {error, binary()})} | {error, binary()}), data_loader_options(), gleam@dict:dict(EDV, {ok, EDW} | {error, binary()})}. -opaque data_loader(EDX, EDY) :: {data_loader, data_loader_state(EDX, EDY)}. -file("src/mochi/dataloader.gleam", 15). -spec default_options() -> data_loader_options(). default_options() -> {data_loader_options, 100, true}. -file("src/mochi/dataloader.gleam", 35). -spec new_with_options( fun((list(EEN)) -> {ok, list({ok, EEO} | {error, binary()})} | {error, binary()}), data_loader_options() ) -> data_loader(EEN, EEO). new_with_options(Batch_load_fn, Options) -> {data_loader, {data_loader_state, Batch_load_fn, Options, maps:new()}}. -file("src/mochi/dataloader.gleam", 31). -spec new( fun((list(EEH)) -> {ok, list({ok, EEI} | {error, binary()})} | {error, binary()}) ) -> data_loader(EEH, EEI). new(Batch_load_fn) -> new_with_options(Batch_load_fn, default_options()). -file("src/mochi/dataloader.gleam", 146). -spec clear_cache(data_loader(EFL, EFM)) -> data_loader(EFL, EFM). clear_cache(Loader) -> {data_loader, State} = Loader, {data_loader, {data_loader_state, erlang:element(2, State), erlang:element(3, State), maps:new()}}. -file("src/mochi/dataloader.gleam", 151). -spec clear_key(data_loader(EFR, EFS), EFR) -> data_loader(EFR, EFS). clear_key(Loader, Key) -> {data_loader, State} = Loader, {data_loader, {data_loader_state, erlang:element(2, State), erlang:element(3, State), gleam@dict:delete(erlang:element(4, State), Key)}}. -file("src/mochi/dataloader.gleam", 159). -spec prime(data_loader(EFX, EFY), EFX, EFY) -> data_loader(EFX, EFY). prime(Loader, Key, Value) -> {data_loader, State} = Loader, case erlang:element(3, erlang:element(3, State)) of true -> {data_loader, {data_loader_state, erlang:element(2, State), erlang:element(3, State), gleam@dict:insert( erlang:element(4, State), Key, {ok, Value} )}}; false -> Loader end. -file("src/mochi/dataloader.gleam", 177). -spec prime_error(data_loader(EGD, EGE), EGD, binary()) -> data_loader(EGD, EGE). prime_error(Loader, Key, Error) -> {data_loader, State} = Loader, case erlang:element(3, erlang:element(3, State)) of true -> {data_loader, {data_loader_state, erlang:element(2, State), erlang:element(3, State), gleam@dict:insert( erlang:element(4, State), Key, {error, Error} )}}; false -> Loader end. -file("src/mochi/dataloader.gleam", 195). -spec fetch_single(data_loader(EGJ, EGK), EGJ) -> {data_loader(EGJ, EGK), {ok, EGK} | {error, binary()}}. fetch_single(Loader, Key) -> {data_loader, State} = Loader, case (erlang:element(2, State))([Key]) of {ok, [Result]} -> New_cache = case erlang:element(3, erlang:element(3, State)) of true -> gleam@dict:insert(erlang:element(4, State), Key, Result); false -> erlang:element(4, State) end, {{data_loader, {data_loader_state, erlang:element(2, State), erlang:element(3, State), New_cache}}, Result}; {ok, Other} -> {Loader, {error, <<"Batch returned wrong number of results: expected 1, got "/utf8, (erlang:integer_to_binary(erlang:length(Other)))/binary>>}}; {error, E} -> {Loader, {error, <<"Batch load failed: "/utf8, E/binary>>}} end. -file("src/mochi/dataloader.gleam", 46). -spec load(data_loader(EET, EEU), EET) -> {data_loader(EET, EEU), {ok, EEU} | {error, binary()}}. load(Loader, Key) -> {data_loader, State} = Loader, case {erlang:element(3, erlang:element(3, State)), gleam_stdlib:map_get(erlang:element(4, State), Key)} of {true, {ok, Cached}} -> {Loader, Cached}; {_, _} -> fetch_single(Loader, Key) end. -file("src/mochi/dataloader.gleam", 219). -spec dedup_preserving_order(list(EGR)) -> list(EGR). dedup_preserving_order(Items) -> {_, Out@1} = gleam@list:fold( Items, {gleam@set:new(), []}, fun(Acc, Item) -> {Seen, Out} = Acc, case gleam@set:contains(Seen, Item) of true -> {Seen, Out}; false -> {gleam@set:insert(Seen, Item), [Item | Out]} end end ), lists:reverse(Out@1). -file("src/mochi/dataloader.gleam", 57). -spec load_many(data_loader(EFB, EFC), list(EFB)) -> {data_loader(EFB, EFC), list({ok, EFC} | {error, binary()})}. load_many(Loader, Keys) -> case Keys of [] -> {Loader, []}; _ -> {data_loader, State} = Loader, {Result_map, Uncached} = gleam@list:fold( Keys, {maps:new(), []}, fun(Acc, Key) -> {Known, To_fetch} = Acc, case {erlang:element(3, erlang:element(3, State)), gleam_stdlib:map_get(erlang:element(4, State), Key)} of {true, {ok, R}} -> {gleam@dict:insert(Known, Key, R), To_fetch}; {_, _} -> {Known, [Key | To_fetch]} end end ), Unique_uncached = dedup_preserving_order(lists:reverse(Uncached)), case Unique_uncached of [] -> Results = gleam@list:map( Keys, fun(K) -> case gleam_stdlib:map_get(Result_map, K) of {ok, R@1} -> R@1; {error, _} -> {error, <<"Key not found"/utf8>>} end end ), {Loader, Results}; _ -> Chunks = gleam@list:sized_chunk( Unique_uncached, erlang:element(2, erlang:element(3, State)) ), case gleam@list:try_map( Chunks, fun(Chunk) -> case (erlang:element(2, State))(Chunk) of {error, E} -> {error, <<"Batch load failed: "/utf8, E/binary>>}; {ok, Results@1} -> Expected = erlang:length(Chunk), Got = erlang:length(Results@1), case Got =:= Expected of false -> {error, <<<<<<"Batch returned wrong number of results: expected "/utf8, (erlang:integer_to_binary( Expected ))/binary>>/binary, ", got "/utf8>>/binary, (erlang:integer_to_binary( Got ))/binary>>}; true -> {ok, gleam@list:zip(Chunk, Results@1)} end end end ) of {error, E@1} -> {Loader, gleam@list:map( Keys, fun(K@1) -> case gleam_stdlib:map_get( Result_map, K@1 ) of {ok, R@2} -> R@2; {error, _} -> {error, E@1} end end )}; {ok, Pairs_per_chunk} -> Fresh = maps:from_list( lists:append(Pairs_per_chunk) ), New_cache = case erlang:element( 3, erlang:element(3, State) ) of true -> maps:merge(erlang:element(4, State), Fresh); false -> erlang:element(4, State) end, New_loader = {data_loader, {data_loader_state, erlang:element(2, State), erlang:element(3, State), New_cache}}, All_results = maps:merge(Result_map, Fresh), Results@2 = gleam@list:map( Keys, fun(K@2) -> case gleam_stdlib:map_get(All_results, K@2) of {ok, R@3} -> R@3; {error, _} -> {error, <<"Key not found in batch results"/utf8>>} end end ), {New_loader, Results@2} end end end. -file("src/mochi/dataloader.gleam", 231). -spec int_loader( fun((integer()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}) ) -> data_loader(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()). int_loader(Lookup) -> new( fun(Keys) -> {ok, gleam@list:map( Keys, fun(Key) -> case gleam@dynamic@decode:run( Key, {decoder, fun gleam@dynamic@decode:decode_int/1} ) of {ok, Id} -> Lookup(Id); {error, _} -> {error, <<"Invalid integer key"/utf8>>} end end )} end ). -file("src/mochi/dataloader.gleam", 246). -spec string_loader( fun((binary()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}) ) -> data_loader(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()). string_loader(Lookup) -> new( fun(Keys) -> {ok, gleam@list:map( Keys, fun(Key) -> case gleam@dynamic@decode:run( Key, {decoder, fun gleam@dynamic@decode:decode_string/1} ) of {ok, S} -> Lookup(S); {error, _} -> {error, <<"Invalid string key"/utf8>>} end end )} end ). -file("src/mochi/dataloader.gleam", 261). -spec int_batch_loader( fun((list(integer())) -> {ok, list(gleam@dynamic:dynamic_())} | {error, binary()}) ) -> data_loader(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()). int_batch_loader(Batch_lookup) -> new( fun(Keys) -> case gleam@list:try_map( Keys, fun(Key) -> gleam@dynamic@decode:run( Key, {decoder, fun gleam@dynamic@decode:decode_int/1} ) end ) of {error, _} -> {error, <<"int_batch_loader: key is not an integer"/utf8>>}; {ok, Int_keys} -> case Batch_lookup(Int_keys) of {ok, Results} -> {ok, gleam@list:map( Results, fun(Field@0) -> {ok, Field@0} end )}; {error, E} -> {error, E} end end end ). -file("src/mochi/dataloader.gleam", 276). -spec string_batch_loader( fun((list(binary())) -> {ok, list(gleam@dynamic:dynamic_())} | {error, binary()}) ) -> data_loader(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()). string_batch_loader(Batch_lookup) -> new( fun(Keys) -> case gleam@list:try_map( Keys, fun(Key) -> gleam@dynamic@decode:run( Key, {decoder, fun gleam@dynamic@decode:decode_string/1} ) end ) of {error, _} -> {error, <<"string_batch_loader: key is not a string"/utf8>>}; {ok, String_keys} -> case Batch_lookup(String_keys) of {ok, Results} -> {ok, gleam@list:map( Results, fun(Field@0) -> {ok, Field@0} end )}; {error, E} -> {error, E} end end end ). -file("src/mochi/dataloader.gleam", 291). -spec int_loader_result( fun((integer()) -> {ok, EHO} | {error, any()}), fun((EHO) -> gleam@dynamic:dynamic_()), binary() ) -> data_loader(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()). int_loader_result(Find_fn, Encoder, Not_found_error) -> int_loader(fun(Id) -> case Find_fn(Id) of {ok, Value} -> {ok, Encoder(Value)}; {error, _} -> {error, Not_found_error} end end). -file("src/mochi/dataloader.gleam", 304). -spec string_loader_result( fun((binary()) -> {ok, EHU} | {error, any()}), fun((EHU) -> gleam@dynamic:dynamic_()), binary() ) -> data_loader(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()). string_loader_result(Find_fn, Encoder, Not_found_error) -> string_loader(fun(Key) -> case Find_fn(Key) of {ok, Value} -> {ok, Encoder(Value)}; {error, _} -> {error, Not_found_error} end end). -file("src/mochi/dataloader.gleam", 317). -spec int_key(integer()) -> gleam@dynamic:dynamic_(). int_key(Id) -> gleam_stdlib:identity(Id). -file("src/mochi/dataloader.gleam", 321). -spec string_key(binary()) -> gleam@dynamic:dynamic_(). string_key(S) -> gleam_stdlib:identity(S).