-module(butterbee@internal@socket). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/butterbee/internal/socket.gleam"). -export([new/1, close/1, send_request/3]). -export_type([web_driver_socket/0, msg/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 web_driver_socket() :: {web_driver_socket, gleam@otp@actor:started(gleam@erlang@process:subject(stratus:internal_message(msg())))}. -type msg() :: {send_command, gleam@erlang@process:subject({ok, binary()} | {error, binary()}), binary()} | close. -file("src/butterbee/internal/socket.gleam", 21). ?DOC(false). -spec logger_response(binary()) -> nil. logger_response(Response) -> _pipe = palabres:debug(<<""/utf8>>), _pipe@1 = palabres:string( _pipe, <<"response"/utf8>>, <<"\n"/utf8, (butterbee@internal@glam:pretty_json(Response))/binary>> ), palabres:log(_pipe@1). -file("src/butterbee/internal/socket.gleam", 27). ?DOC(false). -spec logger_request(binary()) -> nil. logger_request(Request) -> _pipe = palabres:debug(<<""/utf8>>), _pipe@1 = palabres:string( _pipe, <<"request"/utf8>>, <<"\n"/utf8, (butterbee@internal@glam:pretty_json(Request))/binary>> ), palabres:log(_pipe@1). -file("src/butterbee/internal/socket.gleam", 33). ?DOC(false). -spec id_decoder() -> gleam@dynamic@decode:decoder(integer()). id_decoder() -> gleam@dynamic@decode:field( <<"id"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Id) -> gleam@dynamic@decode:success(Id) end ). -file("src/butterbee/internal/socket.gleam", 49). ?DOC(false). -spec new(gleam@http@request:request(binary())) -> {ok, web_driver_socket()} | {error, butterbee@internal@error:butterbee_error()}. new(Request) -> _pipe = palabres:debug(<<"Connecting to WebDriver server"/utf8>>), _pipe@2 = palabres:string( _pipe, <<"url"/utf8>>, begin _pipe@1 = gleam@http@request:to_uri(Request), gleam@uri:to_string(_pipe@1) end ), palabres:log(_pipe@2), State = {ok, maps:new()}, Subject@2 = begin _pipe@3 = stratus:new(Request, State), stratus:on_message(_pipe@3, fun(State@1, Msg, Conn) -> case Msg of {text, Msg@1} -> logger_response(Msg@1), State@3 = case State@1 of {error, Error} -> {error, Error}; {ok, State@2} -> gleam@result:'try'( begin _pipe@4 = gleam@json:parse( Msg@1, id_decoder() ), gleam@result:map_error( _pipe@4, fun(Field@0) -> {could_not_get_id_from_socket_response, Field@0} end ) end, fun(Id) -> gleam@result:'try'( begin _pipe@5 = gleam_stdlib:map_get( State@2, Id ), gleam@result:map_error( _pipe@5, fun(_) -> {response_does_not_have_corresponding_request_id, Id} end ) end, fun(Subject) -> gleam@result:'try'( begin _pipe@6 = gleam@json:parse( Msg@1, butterbidi@definition:message_decoder( ) ), gleam@result:map_error( _pipe@6, fun(Field@0) -> {could_not_parse_socket_response, Field@0} end ) end, fun(Result) -> Msg@2 = case Result of success -> {ok, Msg@1}; error -> {error, Msg@1} end, gleam@erlang@process:send( Subject, Msg@2 ), {ok, begin _pipe@7 = State@2, gleam@dict:drop( _pipe@7, [Id] ) end} end ) end ) end ) end, stratus:continue(State@3); {binary, _} -> stratus:continue(State@1); {user, {send_command, Subject@1, Request@1}} -> Id_decoder = begin gleam@dynamic@decode:field( <<"id"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Id@1) -> gleam@dynamic@decode:success(Id@1) end ) end, State@5 = case State@1 of {error, Error@1} -> {error, Error@1}; {ok, State@4} -> gleam@result:'try'( begin _pipe@8 = gleam@json:parse( Request@1, Id_decoder ), gleam@result:map_error( _pipe@8, fun(Field@0) -> {could_not_get_id_from_send_command, Field@0} end ) end, fun(Id@2) -> logger_request(Request@1), gleam@result:'try'( (case stratus:send_text_message( Conn, Request@1 ) of {ok, _} -> {ok, nil}; {error, Err} -> {error, {web_socket_error, {could_not_send_request, Err}}} end), fun(_) -> {ok, gleam@dict:insert( State@4, Id@2, Subject@1 )} end ) end ) end, stratus:continue(State@5); {user, close} -> _ = stratus:close(Conn, not_provided), stratus:stop() end end) end, gleam@result:'try'( (case butterbee@internal@retry:until_ok( fun() -> stratus:start(Subject@2) end ) of {ok, Subject@3} -> {ok, Subject@3}; {error, Err@1} -> {error, {web_socket_error, {could_not_init, Err@1}}} end), fun(Subject@4) -> {ok, {web_driver_socket, Subject@4}} end ). -file("src/butterbee/internal/socket.gleam", 144). ?DOC(false). -spec close(web_driver_socket()) -> nil. close(Socket) -> _pipe = stratus:to_user_message(close), gleam@erlang@process:send( erlang:element(3, erlang:element(2, Socket)), _pipe ). -file("src/butterbee/internal/socket.gleam", 151). ?DOC(false). -spec send_request( web_driver_socket(), gleam@json:json(), butterbidi@definition:command_data() ) -> {ok, butterbidi@definition:command_response()} | {error, butterbee@internal@error:butterbee_error()}. send_request(Socket, Request, Command) -> Result = gleam@erlang@process:call( erlang:element(3, erlang:element(2, Socket)), 5000, fun(Subject) -> stratus:to_user_message( {send_command, Subject, gleam@json:to_string(Request)} ) end ), case Result of {ok, Result@1} -> case gleam@json:parse( Result@1, butterbidi@definition:command_response_decoder(Command) ) of {ok, Result@2} -> {ok, Result@2}; {error, Error} -> _pipe = palabres:error( <<"Could not parse success response"/utf8>> ), _pipe@1 = palabres:string( _pipe, <<"response"/utf8>>, Result@1 ), _pipe@2 = palabres:string( _pipe@1, <<"error"/utf8>>, gleam@string:inspect(Error) ), palabres:log(_pipe@2), {error, {could_not_parse_response, Error}} end; {error, Result@3} -> case gleam@json:parse( Result@3, butterbidi@definition:error_response_decoder() ) of {ok, Result@4} -> {error, {bidi_error, Result@4}}; {error, Error@1} -> _pipe@3 = palabres:error( <<"Could not parse error response"/utf8>> ), _pipe@4 = palabres:string( _pipe@3, <<"response"/utf8>>, Result@3 ), _pipe@5 = palabres:string( _pipe@4, <<"error"/utf8>>, gleam@string:inspect(Error@1) ), palabres:log(_pipe@5), {error, {could_not_parse_response, Error@1}} end end.