-module(glixir@genserver). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -define(FILEPATH, "src/glixir/genserver.gleam"). -export([start_link/2, start_link_named/3, call_timeout/3, call/2, cast/2, pid/1, lookup_name/1, call_named/2, cast_named/2, stop/1]). -export_type([gen_server/0, gen_server_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. ?MODULEDOC( " Type-safe GenServer interop for Gleam\n" " \n" " This module provides a safe interface to Elixir GenServers from Gleam.\n" ). -opaque gen_server() :: {gen_server, gleam@erlang@process:pid_()}. -type gen_server_error() :: {start_error, binary()} | call_timeout | {call_error, binary()} | {cast_error, binary()} | {not_found, binary()}. -file("src/glixir/genserver.gleam", 52). ?DOC(" Start a GenServer using Module.start_link/1\n"). -spec start_link(binary(), any()) -> {ok, gen_server()} | {error, gen_server_error()}. start_link(Module, Args) -> logging:log( debug, <<<<"🔍 GenServer.start_link called with module: '"/utf8, Module/binary>>/binary, "'"/utf8>> ), Final_module_name = case gleam_stdlib:string_starts_with( Module, <<"Elixir."/utf8>> ) of true -> logging:log( debug, <<"✅ Module already has Elixir. prefix: "/utf8, Module/binary>> ), Module; false -> Prefixed = <<"Elixir."/utf8, Module/binary>>, logging:log( debug, <<<<<<"➕ Adding Elixir. prefix: "/utf8, Module/binary>>/binary, " → "/utf8>>/binary, Prefixed/binary>> ), Prefixed end, logging:log( debug, <<<<"🎯 Final module name for atom creation: '"/utf8, Final_module_name/binary>>/binary, "'"/utf8>> ), Module_atom = erlang:binary_to_atom(Final_module_name), logging:log( debug, <<"🔧 Created atom: "/utf8, (gleam@string:inspect(Module_atom))/binary>> ), logging:log( debug, <<"🚀 Calling gen_server:start_link with args: "/utf8, (gleam@string:inspect(Args))/binary>> ), case gen_server:start_link(Module_atom, Args, []) of {ok, Pid} -> logging:log( info, <<"✅ GenServer started successfully: "/utf8, (gleam@string:inspect(Pid))/binary>> ), {ok, {gen_server, Pid}}; {error, Reason} -> logging:log( error, <<"❌ GenServer start failed: "/utf8, (gleam@string:inspect(Reason))/binary>> ), {error, {start_error, gleam@string:inspect(Reason)}} end. -file("src/glixir/genserver.gleam", 107). ?DOC(" Start a GenServer with a registered name\n"). -spec start_link_named(binary(), binary(), any()) -> {ok, gen_server()} | {error, gen_server_error()}. start_link_named(Module, Name, Args) -> logging:log( debug, <<<<<<<<"🔍 GenServer.start_link_named called with module: '"/utf8, Module/binary>>/binary, "', name: '"/utf8>>/binary, Name/binary>>/binary, "'"/utf8>> ), Final_module_name = case gleam_stdlib:string_starts_with( Module, <<"Elixir."/utf8>> ) of true -> logging:log( debug, <<"✅ Module already has Elixir. prefix: "/utf8, Module/binary>> ), Module; false -> Prefixed = <<"Elixir."/utf8, Module/binary>>, logging:log( debug, <<<<<<"➕ Adding Elixir. prefix: "/utf8, Module/binary>>/binary, " → "/utf8>>/binary, Prefixed/binary>> ), Prefixed end, logging:log( debug, <<<<"🎯 Final module name for atom creation: '"/utf8, Final_module_name/binary>>/binary, "'"/utf8>> ), Module_atom = erlang:binary_to_atom(Final_module_name), logging:log( debug, <<"🔧 Created module atom: "/utf8, (gleam@string:inspect(Module_atom))/binary>> ), Name_atom = erlang:binary_to_atom(Name), logging:log( debug, <<"🏷️ Created name atom: "/utf8, (gleam@string:inspect(Name_atom))/binary>> ), Options = [gleam_stdlib:identity( {erlang:binary_to_atom(<<"name"/utf8>>), Name_atom} )], logging:log( debug, <<"⚙️ GenServer options: "/utf8, (gleam@string:inspect(Options))/binary>> ), logging:log( debug, <<"🚀 Calling gen_server:start_link with args: "/utf8, (gleam@string:inspect(Args))/binary>> ), case gen_server:start_link(Module_atom, Args, Options) of {ok, Pid} -> logging:log( info, <<<<<<"✅ Named GenServer '"/utf8, Name/binary>>/binary, "' started successfully: "/utf8>>/binary, (gleam@string:inspect(Pid))/binary>> ), {ok, {gen_server, Pid}}; {error, Reason} -> logging:log( error, <<<<<<"❌ Named GenServer '"/utf8, Name/binary>>/binary, "' start failed: "/utf8>>/binary, (gleam@string:inspect(Reason))/binary>> ), {error, {start_error, gleam@string:inspect(Reason)}} end. -file("src/glixir/genserver.gleam", 197). ?DOC(" Send a synchronous call with custom timeout\n"). -spec call_timeout(gen_server(), any(), integer()) -> {ok, any()} | {error, gen_server_error()}. call_timeout(Server, Request, Timeout) -> {gen_server, Pid} = Server, logging:log( debug, <<<<<<"📞⏱️ GenServer.call_timeout to PID "/utf8, (gleam@string:inspect(Pid))/binary>>/binary, " with timeout "/utf8>>/binary, (gleam@string:inspect(Timeout))/binary>> ), logging:log( debug, <<"📞⏱️ Request: "/utf8, (gleam@string:inspect(Request))/binary>> ), Response = gen_server:call(Pid, Request, Timeout), logging:log( debug, <<"📞✅ GenServer call response: "/utf8, (gleam@string:inspect(Response))/binary>> ), {ok, gleam_stdlib:identity(Response)}. -file("src/glixir/genserver.gleam", 188). ?DOC(" Send a synchronous call to the GenServer (5s timeout)\n"). -spec call(gen_server(), any()) -> {ok, any()} | {error, gen_server_error()}. call(Server, Request) -> logging:log( debug, <<"📞 GenServer.call with request: "/utf8, (gleam@string:inspect(Request))/binary>> ), call_timeout(Server, Request, 5000). -file("src/glixir/genserver.gleam", 249). ?DOC(" Send an asynchronous cast to the GenServer\n"). -spec cast(gen_server(), any()) -> {ok, nil} | {error, gen_server_error()}. cast(Server, Request) -> {gen_server, Pid} = Server, logging:log( debug, <<<<<<"📨 GenServer.cast to PID "/utf8, (gleam@string:inspect(Pid))/binary>>/binary, " with request: "/utf8>>/binary, (gleam@string:inspect(Request))/binary>> ), Result = gen_server:cast(Pid, Request), logging:log( debug, <<"📨✅ GenServer cast result: "/utf8, (gleam@string:inspect(Result))/binary>> ), case erlang:atom_to_binary(Result) of <<"ok"/utf8>> -> logging:log(debug, <<"📨✅ Cast successful"/utf8>>), {ok, nil}; Other -> logging:log(error, <<"📨❌ Cast failed with: "/utf8, Other/binary>>), {error, {cast_error, Other}} end. -file("src/glixir/genserver.gleam", 303). ?DOC(" Get the PID of a GenServer\n"). -spec pid(gen_server()) -> gleam@erlang@process:pid_(). pid(Server) -> {gen_server, P} = Server, logging:log( debug, <<"🆔 GenServer.pid returning: "/utf8, (gleam@string:inspect(P))/binary>> ), P. -file("src/glixir/genserver.gleam", 310). ?DOC(" Look up a GenServer by registered name\n"). -spec lookup_name(binary()) -> {ok, gen_server()} | {error, gen_server_error()}. lookup_name(Name) -> logging:log( debug, <<<<"🔍 GenServer.lookup_name for: '"/utf8, Name/binary>>/binary, "'"/utf8>> ), Name_atom = erlang:binary_to_atom(Name), logging:log( debug, <<"🔍 Created lookup atom: "/utf8, (gleam@string:inspect(Name_atom))/binary>> ), Pid_result = erlang:whereis(Name_atom), logging:log( debug, <<"🔍 whereis result: "/utf8, (gleam@string:inspect(Pid_result))/binary>> ), case gleam_stdlib:classify_dynamic(Pid_result) of <<"Pid"/utf8>> -> logging:log( info, <<<<"🔍✅ Found GenServer PID for '"/utf8, Name/binary>>/binary, "'"/utf8>> ), {ok, {gen_server, gleam_stdlib:identity(Pid_result)}}; <<"Atom"/utf8>> -> logging:log( warning, <<<<"🔍❌ GenServer '"/utf8, Name/binary>>/binary, "' returned atom (likely 'undefined')"/utf8>> ), {error, {not_found, Name}}; Other -> logging:log( warning, <<<<<<"🔍❌ GenServer '"/utf8, Name/binary>>/binary, "' not found, got type: "/utf8>>/binary, Other/binary>> ), {error, {not_found, Name}} end. -file("src/glixir/genserver.gleam", 224). ?DOC(" Call a named GenServer\n"). -spec call_named(binary(), any()) -> {ok, any()} | {error, gen_server_error()}. call_named(Name, Request) -> logging:log( debug, <<<<<<"📞🏷️ GenServer.call_named to '"/utf8, Name/binary>>/binary, "' with request: "/utf8>>/binary, (gleam@string:inspect(Request))/binary>> ), case lookup_name(Name) of {ok, Server} -> logging:log( debug, <<"📞🏷️✅ Found named GenServer, making call"/utf8>> ), call(Server, Request); {error, E} -> logging:log( error, <<"📞🏷️❌ Named GenServer lookup failed: "/utf8, (gleam@string:inspect(E))/binary>> ), {error, E} end. -file("src/glixir/genserver.gleam", 278). ?DOC(" Cast to a named GenServer\n"). -spec cast_named(binary(), any()) -> {ok, nil} | {error, gen_server_error()}. cast_named(Name, Request) -> logging:log( debug, <<<<<<"📨🏷️ GenServer.cast_named to '"/utf8, Name/binary>>/binary, "' with request: "/utf8>>/binary, (gleam@string:inspect(Request))/binary>> ), case lookup_name(Name) of {ok, Server} -> logging:log( debug, <<"📨🏷️✅ Found named GenServer, making cast"/utf8>> ), cast(Server, Request); {error, E} -> logging:log( error, <<"📨🏷️❌ Named GenServer lookup failed: "/utf8, (gleam@string:inspect(E))/binary>> ), {error, E} end. -file("src/glixir/genserver.gleam", 345). ?DOC(" Stop a GenServer gracefully\n"). -spec stop(gen_server()) -> {ok, nil} | {error, gen_server_error()}. stop(Server) -> logging:log(debug, <<"🛑 GenServer.stop called"/utf8>>), cast(Server, erlang:binary_to_atom(<<"stop"/utf8>>)).