Current section
Files
Jump to
Current section
Files
src/telega@flow@engine.erl
-module(telega@flow@engine).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/telega/flow/engine.gleam").
-export([emit_flow_event/3, handle_error/4, generate_wait_token/1, apply_middlewares/4, execute_subflow_step/4, execute_step/3, start_or_resume/5, resume_with_instance/4, resume_with_token/4, extract_ids_from_context/1]).
-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(" Core execution engine, hooks, middleware application, and conditionals.\n").
-file("src/telega/flow/engine.gleam", 26).
?DOC(false).
-spec emit_flow_event(
binary(),
telega@flow@types:flow_instance(),
list({binary(), integer()})
) -> nil.
emit_flow_event(Event, Instance, Measurements) ->
telega@telemetry:execute(
[<<"telega"/utf8>>, <<"flow"/utf8>>, Event],
Measurements,
[{<<"flow_name"/utf8>>, {string_value, erlang:element(3, Instance)}},
{<<"step"/utf8>>,
{string_value, erlang:element(2, erlang:element(6, Instance))}}]
).
-file("src/telega/flow/engine.gleam", 233).
?DOC(false).
-spec handle_error(
telega@flow@types:flow(any(), BCKS, BCKT, BCKU),
telega@bot:context(BCKS, BCKT, BCKU),
telega@flow@types:flow_instance(),
gleam@option:option(BCKT)
) -> {ok, telega@bot:context(BCKS, BCKT, BCKU)} | {error, BCKT}.
handle_error(Flow, Ctx, Instance, Error) ->
case erlang:element(9, Flow) of
{some, Handler} ->
case Handler(Ctx, Instance, Error) of
{ok, New_ctx} ->
{ok, New_ctx};
{error, _} ->
{ok, Ctx}
end;
none ->
{ok, Ctx}
end.
-file("src/telega/flow/engine.gleam", 1120).
-spec handle_subflow_error(
telega@flow@types:flow(gleam@dynamic:dynamic_(), BCWC, BCWD, BCWE),
telega@bot:context(BCWC, BCWD, BCWE),
telega@flow@types:flow_instance(),
gleam@option:option(BCWD),
telega@flow@types:subflow_config(any(), BCWC, BCWD, BCWE)
) -> {ok, telega@bot:context(BCWC, BCWD, BCWE)} | {error, BCWD}.
handle_subflow_error(Flow, Ctx, Instance, Error, _) ->
case erlang:element(9, Flow) of
{some, Handler} ->
case Handler(Ctx, Instance, Error) of
{ok, New_ctx} ->
{ok, New_ctx};
{error, _} ->
{ok, Ctx}
end;
none ->
{ok, Ctx}
end.
-file("src/telega/flow/engine.gleam", 278).
?DOC(false).
-spec generate_wait_token(telega@flow@types:flow_instance()) -> binary().
generate_wait_token(Instance) ->
<<<<(erlang:element(2, Instance))/binary, ":"/utf8>>/binary,
(erlang:integer_to_binary(telega@internal@utils:current_time_ms()))/binary>>.
-file("src/telega/flow/engine.gleam", 1082).
-spec return_to_parent_flow(
telega@bot:context(BCVK, BCVL, BCVM),
telega@flow@types:flow_instance(),
gleam@dict:dict(binary(), binary()),
telega@flow@types:subflow_config(any(), BCVK, BCVL, BCVM)
) -> {ok, telega@bot:context(BCVK, BCVL, BCVM)} | {error, BCVL}.
return_to_parent_flow(Ctx, Instance, Result, Config) ->
case erlang:element(5, erlang:element(6, Instance)) of
[Frame | Rest_stack] ->
Temp_instance = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record = erlang:element(6, Instance),
{flow_state,
erlang:element(2, _record),
erlang:element(4, Frame),
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record)}
end,
erlang:element(7, Instance),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
erlang:element(11, Instance)},
Mapped_instance = (erlang:element(6, Config))(Result, Temp_instance),
Updated_instance = {flow_instance,
erlang:element(2, Mapped_instance),
erlang:element(2, Frame),
erlang:element(4, Mapped_instance),
erlang:element(5, Mapped_instance),
begin
_record@1 = erlang:element(6, Mapped_instance),
{flow_state,
erlang:element(3, Frame),
erlang:element(3, _record@1),
[erlang:element(3, Frame) |
erlang:element(
4,
erlang:element(6, Mapped_instance)
)],
Rest_stack,
erlang:element(6, _record@1)}
end,
maps:new(),
erlang:element(8, Mapped_instance),
erlang:element(9, Mapped_instance),
erlang:element(10, Mapped_instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(
2,
erlang:element(7, erlang:element(3, Config))
))(Updated_instance) of
{ok, _} ->
{ok, Ctx};
{error, _} ->
{ok, Ctx}
end;
[] ->
{ok, Ctx}
end.
-file("src/telega/flow/engine.gleam", 260).
?DOC(false).
-spec apply_middlewares(
telega@bot:context(BCLO, BCLP, BCLQ),
telega@flow@types:flow_instance(),
fun(() -> {ok,
{telega@bot:context(BCLO, BCLP, BCLQ),
telega@flow@types:flow_action(BCLU),
telega@flow@types:flow_instance()}} |
{error, BCLP}),
list(fun((telega@bot:context(BCLO, BCLP, BCLQ), telega@flow@types:flow_instance(), fun(() -> {ok,
{telega@bot:context(BCLO, BCLP, BCLQ),
telega@flow@types:flow_action(BCLU),
telega@flow@types:flow_instance()}} |
{error, BCLP})) -> {ok,
{telega@bot:context(BCLO, BCLP, BCLQ),
telega@flow@types:flow_action(BCLU),
telega@flow@types:flow_instance()}} |
{error, BCLP}))
) -> {ok,
{telega@bot:context(BCLO, BCLP, BCLQ),
telega@flow@types:flow_action(BCLU),
telega@flow@types:flow_instance()}} |
{error, BCLP}.
apply_middlewares(Ctx, Instance, Handler, Middlewares) ->
case Middlewares of
[] ->
Handler();
[Middleware | Rest] ->
Middleware(
Ctx,
Instance,
fun() -> apply_middlewares(Ctx, Instance, Handler, Rest) end
)
end.
-file("src/telega/flow/engine.gleam", 918).
-spec process_subflow_action(
telega@flow@types:flow(gleam@dynamic:dynamic_(), BCUP, BCUQ, BCUR),
telega@bot:context(BCUP, BCUQ, BCUR),
telega@flow@types:flow_action(gleam@dynamic:dynamic_()),
telega@flow@types:flow_instance(),
telega@flow@types:subflow_config(any(), BCUP, BCUQ, BCUR)
) -> {ok, telega@bot:context(BCUP, BCUQ, BCUR)} | {error, BCUQ}.
process_subflow_action(Flow, Ctx, Action, Instance, Config) ->
case Action of
{complete, Data} ->
return_to_parent_flow(Ctx, Instance, Data, Config);
{exit, {some, Data}} ->
return_to_parent_flow(Ctx, Instance, Data, Config);
{exit, none} ->
return_to_parent_flow(
Ctx,
Instance,
erlang:element(3, erlang:element(6, Instance)),
Config
);
{return_from_subflow, Result} ->
return_to_parent_flow(Ctx, Instance, Result, Config);
cancel ->
emit_flow_event(
<<"cancel"/utf8>>,
Instance,
[{<<"count"/utf8>>, 1}]
),
_ = (erlang:element(4, erlang:element(7, Flow)))(
erlang:element(2, Instance)
),
{ok, Ctx};
{next, Step} ->
Step_name = (erlang:element(5, Flow))(Step),
Updated_instance = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record = erlang:element(6, Instance),
{flow_state,
Step_name,
erlang:element(3, _record),
[erlang:element(2, erlang:element(6, Instance)) |
erlang:element(4, erlang:element(6, Instance))],
erlang:element(5, _record),
erlang:element(6, _record)}
end,
gleam@dict:delete(
erlang:element(7, Instance),
<<"__wait_result"/utf8>>
),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(Updated_instance) of
{ok, _} ->
execute_subflow_step(Flow, Ctx, Updated_instance, Config);
{error, Err} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err},
Config
)
end;
{next_string, Step_name@1} ->
Updated_instance@1 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@1 = erlang:element(6, Instance),
{flow_state,
Step_name@1,
erlang:element(3, _record@1),
[erlang:element(2, erlang:element(6, Instance)) |
erlang:element(4, erlang:element(6, Instance))],
erlang:element(5, _record@1),
erlang:element(6, _record@1)}
end,
gleam@dict:delete(
erlang:element(7, Instance),
<<"__wait_result"/utf8>>
),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@1
) of
{ok, _} ->
execute_subflow_step(Flow, Ctx, Updated_instance@1, Config);
{error, Err@1} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err@1},
Config
)
end;
{go_to, Step@1} ->
Step_name@2 = (erlang:element(5, Flow))(Step@1),
Updated_instance@2 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
{flow_state,
Step_name@2,
erlang:element(3, erlang:element(6, Instance)),
[Step_name@2],
erlang:element(5, erlang:element(6, Instance)),
none},
maps:new(),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@2
) of
{ok, _} ->
execute_subflow_step(Flow, Ctx, Updated_instance@2, Config);
{error, Err@2} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err@2},
Config
)
end;
{jump, Step@2} ->
Step_name@3 = (erlang:element(5, Flow))(Step@2),
Updated_instance@3 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@2 = erlang:element(6, Instance),
{flow_state,
Step_name@3,
erlang:element(3, _record@2),
erlang:element(4, _record@2),
erlang:element(5, _record@2),
erlang:element(6, _record@2)}
end,
gleam@dict:delete(
erlang:element(7, Instance),
<<"__wait_result"/utf8>>
),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@3
) of
{ok, _} ->
execute_subflow_step(Flow, Ctx, Updated_instance@3, Config);
{error, Err@3} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err@3},
Config
)
end;
back ->
case erlang:element(4, erlang:element(6, Instance)) of
[Previous_step | Rest] ->
Updated_instance@4 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@3 = erlang:element(6, Instance),
{flow_state,
Previous_step,
erlang:element(3, _record@3),
Rest,
erlang:element(5, _record@3),
erlang:element(6, _record@3)}
end,
gleam@dict:delete(
erlang:element(7, Instance),
<<"__wait_result"/utf8>>
),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@4
) of
{ok, _} ->
execute_subflow_step(
Flow,
Ctx,
Updated_instance@4,
Config
);
{error, Err@4} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err@4},
Config
)
end;
[] ->
{ok, Ctx}
end;
wait ->
Token = generate_wait_token(Instance),
Updated_instance@5 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
erlang:element(7, Instance),
{some, Token},
none,
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@5
) of
{ok, _} ->
{ok, Ctx};
{error, Err@5} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err@5},
Config
)
end;
wait_callback ->
Token = generate_wait_token(Instance),
Updated_instance@5 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
erlang:element(7, Instance),
{some, Token},
none,
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@5
) of
{ok, _} ->
{ok, Ctx};
{error, Err@5} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err@5},
Config
)
end;
{wait_with_timeout, Timeout_ms} ->
Token@1 = generate_wait_token(Instance),
Wait_timeout_at = telega@internal@utils:current_time_ms() + Timeout_ms,
Updated_instance@6 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
erlang:element(7, Instance),
{some, Token@1},
{some, Wait_timeout_at},
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@6
) of
{ok, _} ->
{ok, Ctx};
{error, Err@6} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err@6},
Config
)
end;
{wait_callback_with_timeout, Timeout_ms} ->
Token@1 = generate_wait_token(Instance),
Wait_timeout_at = telega@internal@utils:current_time_ms() + Timeout_ms,
Updated_instance@6 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
erlang:element(7, Instance),
{some, Token@1},
{some, Wait_timeout_at},
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@6
) of
{ok, _} ->
{ok, Ctx};
{error, Err@6} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err@6},
Config
)
end;
{start_parallel, _, _} ->
{ok, Ctx};
{complete_parallel_step, _, _} ->
{ok, Ctx};
{enter_subflow, _, _} ->
{ok, Ctx}
end.
-file("src/telega/flow/engine.gleam", 887).
?DOC(false).
-spec execute_subflow_step(
telega@flow@types:flow(gleam@dynamic:dynamic_(), BCTV, BCTW, BCTX),
telega@bot:context(BCTV, BCTW, BCTX),
telega@flow@types:flow_instance(),
telega@flow@types:subflow_config(any(), BCTV, BCTW, BCTX)
) -> {ok, telega@bot:context(BCTV, BCTW, BCTX)} | {error, BCTW}.
execute_subflow_step(Flow, Ctx, Instance, Config) ->
case gleam_stdlib:map_get(
erlang:element(3, Flow),
erlang:element(2, erlang:element(6, Instance))
) of
{ok, Step_config} ->
Handler_fn = fun() ->
(erlang:element(2, Step_config))(Ctx, Instance)
end,
Started_at = erlang:monotonic_time(),
Result = apply_middlewares(
Ctx,
Instance,
Handler_fn,
lists:append(
erlang:element(10, Flow),
erlang:element(3, Step_config)
)
),
emit_flow_event(
<<"step"/utf8>>,
Instance,
[{<<"duration"/utf8>>, erlang:monotonic_time() - Started_at}]
),
case Result of
{ok, {New_ctx, Action, New_instance}} ->
process_subflow_action(
Flow,
New_ctx,
Action,
New_instance,
Config
);
{error, Err} ->
handle_subflow_error(
Flow,
Ctx,
Instance,
{some, Err},
Config
)
end;
{error, _} ->
handle_subflow_error(Flow, Ctx, Instance, none, Config)
end.
-file("src/telega/flow/engine.gleam", 708).
-spec run_flow_exit_hook(
gleam@option:option(fun((telega@bot:context(BCQC, BCQD, BCQE), telega@flow@types:flow_instance()) -> {ok,
telega@bot:context(BCQC, BCQD, BCQE)} |
{error, BCQD})),
telega@bot:context(BCQC, BCQD, BCQE),
telega@flow@types:flow_instance()
) -> {ok, telega@bot:context(BCQC, BCQD, BCQE)} | {error, BCQD}.
run_flow_exit_hook(Hook, Ctx, Instance) ->
case Hook of
{some, Exit_fn} ->
Exit_fn(Ctx, Instance);
none ->
{ok, Ctx}
end.
-file("src/telega/flow/engine.gleam", 860).
-spec merge_parallel_results(
gleam@dict:dict(binary(), binary()),
gleam@dict:dict(binary(), gleam@dict:dict(binary(), binary()))
) -> gleam@dict:dict(binary(), binary()).
merge_parallel_results(Base_data, Parallel_results) ->
gleam@dict:fold(
Parallel_results,
Base_data,
fun(Acc, Step_name, Step_results) ->
gleam@dict:fold(
Step_results,
Acc,
fun(Inner_acc, Key, Value) ->
gleam@dict:insert(
Inner_acc,
<<<<Step_name/binary, "."/utf8>>/binary, Key/binary>>,
Value
)
end
)
end
).
-file("src/telega/flow/engine.gleam", 675).
-spec run_leave_hook(
gleam@option:option(fun((telega@bot:context(BCOJ, BCOK, BCOL), telega@flow@types:flow_instance()) -> {ok,
{telega@bot:context(BCOJ, BCOK, BCOL),
telega@flow@types:flow_instance()}} |
{error, BCOK})),
telega@bot:context(BCOJ, BCOK, BCOL),
telega@flow@types:flow_instance()
) -> {ok,
{telega@bot:context(BCOJ, BCOK, BCOL),
telega@flow@types:flow_instance()}} |
{error, BCOK}.
run_leave_hook(Hook, Ctx, Instance) ->
case Hook of
{some, Leave_fn} ->
Leave_fn(Ctx, Instance);
none ->
{ok, {Ctx, Instance}}
end.
-file("src/telega/flow/engine.gleam", 664).
-spec run_enter_hook(
gleam@option:option(fun((telega@bot:context(BCNU, BCNV, BCNW), telega@flow@types:flow_instance()) -> {ok,
{telega@bot:context(BCNU, BCNV, BCNW),
telega@flow@types:flow_instance()}} |
{error, BCNV})),
telega@bot:context(BCNU, BCNV, BCNW),
telega@flow@types:flow_instance()
) -> {ok,
{telega@bot:context(BCNU, BCNV, BCNW),
telega@flow@types:flow_instance()}} |
{error, BCNV}.
run_enter_hook(Hook, Ctx, Instance) ->
case Hook of
{some, Enter_fn} ->
Enter_fn(Ctx, Instance);
none ->
{ok, {Ctx, Instance}}
end.
-file("src/telega/flow/engine.gleam", 697).
-spec run_flow_leave_hook(
gleam@option:option(fun((telega@bot:context(BCPN, BCPO, BCPP), telega@flow@types:flow_instance()) -> {ok,
{telega@bot:context(BCPN, BCPO, BCPP),
telega@flow@types:flow_instance()}} |
{error, BCPO})),
telega@bot:context(BCPN, BCPO, BCPP),
telega@flow@types:flow_instance()
) -> {ok,
{telega@bot:context(BCPN, BCPO, BCPP),
telega@flow@types:flow_instance()}} |
{error, BCPO}.
run_flow_leave_hook(Hook, Ctx, Instance) ->
case Hook of
{some, Leave_fn} ->
Leave_fn(Ctx, Instance);
none ->
{ok, {Ctx, Instance}}
end.
-file("src/telega/flow/engine.gleam", 770).
-spec start_subflow_execution(
telega@flow@types:flow(BCRX, BCRY, BCRZ, BCSA),
telega@bot:context(BCRY, BCRZ, BCSA),
telega@flow@types:flow_instance(),
telega@flow@types:subflow_config(BCRX, BCRY, BCRZ, BCSA)
) -> {ok, telega@bot:context(BCRY, BCRZ, BCSA)} | {error, BCRZ}.
start_subflow_execution(Parent_flow, Ctx, Instance, Config) ->
case run_flow_leave_hook(erlang:element(15, Parent_flow), Ctx, Instance) of
{ok, {Ctx_after_leave, Instance_after_leave}} ->
Return_step = (erlang:element(5, Parent_flow))(
erlang:element(4, Config)
),
Stack_frame = {flow_stack_frame,
erlang:element(2, Parent_flow),
Return_step,
erlang:element(3, erlang:element(6, Instance_after_leave))},
Subflow_data = (erlang:element(5, Config))(Instance_after_leave),
Subflow_initial_step = (erlang:element(5, erlang:element(3, Config)))(
erlang:element(4, erlang:element(3, Config))
),
Updated_instance = {flow_instance,
erlang:element(2, Instance_after_leave),
erlang:element(2, erlang:element(3, Config)),
erlang:element(4, Instance_after_leave),
erlang:element(5, Instance_after_leave),
{flow_state,
Subflow_initial_step,
Subflow_data,
[Subflow_initial_step],
[Stack_frame |
erlang:element(
5,
erlang:element(6, Instance_after_leave)
)],
none},
maps:new(),
erlang:element(8, Instance_after_leave),
erlang:element(9, Instance_after_leave),
erlang:element(10, Instance_after_leave),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Parent_flow)))(
Updated_instance
) of
{ok, _} ->
execute_subflow_step(
erlang:element(3, Config),
Ctx_after_leave,
Updated_instance,
Config
);
{error, Err} ->
handle_error(Parent_flow, Ctx, Instance, {some, Err})
end;
{error, Err@1} ->
handle_error(Parent_flow, Ctx, Instance, {some, Err@1})
end.
-file("src/telega/flow/engine.gleam", 760).
-spec check_subflow_trigger(
telega@flow@types:flow(BCRK, BCRL, BCRM, BCRN),
telega@flow@types:flow_instance()
) -> gleam@option:option(telega@flow@types:subflow_config(BCRK, BCRL, BCRM, BCRN)).
check_subflow_trigger(Flow, Instance) ->
_pipe = gleam@list:find(
erlang:element(13, Flow),
fun(Config) ->
erlang:element(2, Config) =:= erlang:element(
2,
erlang:element(6, Instance)
)
end
),
gleam@option:from_result(_pipe).
-file("src/telega/flow/engine.gleam", 750).
-spec check_parallel_trigger(
telega@flow@types:flow(BCRA, any(), any(), any()),
telega@flow@types:flow_instance()
) -> gleam@option:option(telega@flow@types:parallel_config(BCRA)).
check_parallel_trigger(Flow, Instance) ->
_pipe = gleam@list:find(
erlang:element(12, Flow),
fun(Config) ->
erlang:element(2, Config) =:= erlang:element(
2,
erlang:element(6, Instance)
)
end
),
gleam@option:from_result(_pipe).
-file("src/telega/flow/engine.gleam", 719).
-spec check_conditionals(
telega@flow@types:flow(any(), any(), any(), any()),
telega@flow@types:flow_instance()
) -> gleam@option:option(binary()).
check_conditionals(Flow, Instance) ->
gleam@list:fold(
erlang:element(11, Flow),
none,
fun(Acc, Conditional) -> case Acc of
{some, _} ->
Acc;
none ->
case erlang:element(2, Conditional) =:= erlang:element(
2,
erlang:element(6, Instance)
) of
true ->
_pipe = gleam@list:fold(
erlang:element(3, Conditional),
none,
fun(Inner_acc, Cond) -> case Inner_acc of
{some, _} ->
Inner_acc;
none ->
{Check_fn, Step} = Cond,
case Check_fn(Instance) of
true ->
{some,
(erlang:element(5, Flow))(
Step
)};
false ->
none
end
end end
),
gleam@option:'or'(
_pipe,
{some,
(erlang:element(5, Flow))(
erlang:element(4, Conditional)
)}
);
false ->
none
end
end end
).
-file("src/telega/flow/engine.gleam", 303).
-spec process_action(
telega@flow@types:flow(BCND, BCNE, BCNF, BCNG),
telega@bot:context(BCNE, BCNF, BCNG),
telega@flow@types:flow_action(BCND),
telega@flow@types:flow_instance()
) -> {ok, telega@bot:context(BCNE, BCNF, BCNG)} | {error, BCNF}.
process_action(Flow, Ctx, Action, Instance) ->
case Action of
{next, Step} ->
Step_name = (erlang:element(5, Flow))(Step),
Updated_instance = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record = erlang:element(6, Instance),
{flow_state,
Step_name,
erlang:element(3, _record),
[erlang:element(2, erlang:element(6, Instance)) |
erlang:element(4, erlang:element(6, Instance))],
erlang:element(5, _record),
erlang:element(6, _record)}
end,
gleam@dict:delete(
erlang:element(7, Instance),
<<"__wait_result"/utf8>>
),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(Updated_instance) of
{ok, _} ->
execute_step(Flow, Ctx, Updated_instance);
{error, Err} ->
handle_error(Flow, Ctx, Instance, {some, Err})
end;
{next_string, Step_name@1} ->
Updated_instance@1 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@1 = erlang:element(6, Instance),
{flow_state,
Step_name@1,
erlang:element(3, _record@1),
[erlang:element(2, erlang:element(6, Instance)) |
erlang:element(4, erlang:element(6, Instance))],
erlang:element(5, _record@1),
erlang:element(6, _record@1)}
end,
gleam@dict:delete(
erlang:element(7, Instance),
<<"__wait_result"/utf8>>
),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@1
) of
{ok, _} ->
execute_step(Flow, Ctx, Updated_instance@1);
{error, Err@1} ->
handle_error(Flow, Ctx, Instance, {some, Err@1})
end;
{return_from_subflow, Result} ->
case erlang:element(5, erlang:element(6, Instance)) of
[Frame | Rest_stack] ->
Updated_instance@2 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@2 = erlang:element(6, Instance),
{flow_state,
erlang:element(3, Frame),
maps:merge(
erlang:element(
3,
erlang:element(6, Instance)
),
Result
),
erlang:element(4, _record@2),
Rest_stack,
erlang:element(6, _record@2)}
end,
erlang:element(7, Instance),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@2
) of
{ok, _} ->
execute_step(Flow, Ctx, Updated_instance@2);
{error, Err@2} ->
handle_error(Flow, Ctx, Instance, {some, Err@2})
end;
[] ->
{ok, Ctx}
end;
{start_parallel, Steps, Join_at} ->
Step_names = gleam@list:map(Steps, erlang:element(5, Flow)),
Join_step_name = (erlang:element(5, Flow))(Join_at),
Parallel_state = {parallel_state,
Step_names,
[],
maps:new(),
Join_step_name},
Updated_instance@3 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@3 = erlang:element(6, Instance),
{flow_state,
erlang:element(2, _record@3),
erlang:element(3, _record@3),
erlang:element(4, _record@3),
erlang:element(5, _record@3),
{some, Parallel_state}}
end,
erlang:element(7, Instance),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@3
) of
{ok, _} ->
case Step_names of
[First | _] ->
Step_instance = {flow_instance,
erlang:element(2, Updated_instance@3),
erlang:element(3, Updated_instance@3),
erlang:element(4, Updated_instance@3),
erlang:element(5, Updated_instance@3),
begin
_record@4 = erlang:element(
6,
Updated_instance@3
),
{flow_state,
First,
erlang:element(3, _record@4),
erlang:element(4, _record@4),
erlang:element(5, _record@4),
erlang:element(6, _record@4)}
end,
erlang:element(7, Updated_instance@3),
erlang:element(8, Updated_instance@3),
erlang:element(9, Updated_instance@3),
erlang:element(10, Updated_instance@3),
erlang:element(11, Updated_instance@3)},
execute_step(Flow, Ctx, Step_instance);
[] ->
{ok, Ctx}
end;
{error, Err@3} ->
handle_error(Flow, Ctx, Instance, {some, Err@3})
end;
{complete_parallel_step, Step@1, Result@1} ->
case erlang:element(6, erlang:element(6, Instance)) of
{some, Parallel_state@1} ->
Step_name@2 = (erlang:element(5, Flow))(Step@1),
Updated_parallel = {parallel_state,
gleam@list:filter(
erlang:element(2, Parallel_state@1),
fun(S) -> S /= Step_name@2 end
),
[Step_name@2 | erlang:element(3, Parallel_state@1)],
gleam@dict:insert(
erlang:element(4, Parallel_state@1),
Step_name@2,
Result@1
),
erlang:element(5, Parallel_state@1)},
case erlang:element(2, Updated_parallel) of
[] ->
Updated_instance@4 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@5 = erlang:element(6, Instance),
{flow_state,
erlang:element(5, Updated_parallel),
merge_parallel_results(
erlang:element(
3,
erlang:element(6, Instance)
),
erlang:element(4, Updated_parallel)
),
erlang:element(4, _record@5),
erlang:element(5, _record@5),
none}
end,
erlang:element(7, Instance),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@4
) of
{ok, _} ->
execute_step(Flow, Ctx, Updated_instance@4);
{error, Err@4} ->
handle_error(
Flow,
Ctx,
Instance,
{some, Err@4}
)
end;
[Next | _] ->
Updated_instance@5 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@6 = erlang:element(6, Instance),
{flow_state,
Next,
erlang:element(3, _record@6),
erlang:element(4, _record@6),
erlang:element(5, _record@6),
{some, Updated_parallel}}
end,
erlang:element(7, Instance),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@5
) of
{ok, _} ->
execute_step(Flow, Ctx, Updated_instance@5);
{error, Err@5} ->
handle_error(
Flow,
Ctx,
Instance,
{some, Err@5}
)
end
end;
none ->
{ok, Ctx}
end;
{go_to, Step@2} ->
Step_name@3 = (erlang:element(5, Flow))(Step@2),
Updated_instance@6 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
{flow_state,
Step_name@3,
erlang:element(3, erlang:element(6, Instance)),
[Step_name@3],
[],
none},
maps:new(),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@6
) of
{ok, _} ->
execute_step(Flow, Ctx, Updated_instance@6);
{error, Err@6} ->
handle_error(Flow, Ctx, Instance, {some, Err@6})
end;
{jump, Step@3} ->
Step_name@4 = (erlang:element(5, Flow))(Step@3),
Updated_instance@7 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@7 = erlang:element(6, Instance),
{flow_state,
Step_name@4,
erlang:element(3, _record@7),
erlang:element(4, _record@7),
erlang:element(5, _record@7),
erlang:element(6, _record@7)}
end,
gleam@dict:delete(
erlang:element(7, Instance),
<<"__wait_result"/utf8>>
),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@7
) of
{ok, _} ->
execute_step(Flow, Ctx, Updated_instance@7);
{error, Err@7} ->
handle_error(Flow, Ctx, Instance, {some, Err@7})
end;
back ->
case erlang:element(4, erlang:element(6, Instance)) of
[Previous_step | Rest] ->
Updated_instance@8 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@8 = erlang:element(6, Instance),
{flow_state,
Previous_step,
erlang:element(3, _record@8),
Rest,
erlang:element(5, _record@8),
erlang:element(6, _record@8)}
end,
gleam@dict:delete(
erlang:element(7, Instance),
<<"__wait_result"/utf8>>
),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@8
) of
{ok, _} ->
execute_step(Flow, Ctx, Updated_instance@8);
{error, Err@8} ->
handle_error(Flow, Ctx, Instance, {some, Err@8})
end;
[] ->
{ok, Ctx}
end;
{complete, Data} ->
Completed_instance = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record@9 = erlang:element(6, Instance),
{flow_state,
erlang:element(2, _record@9),
Data,
erlang:element(4, _record@9),
erlang:element(5, _record@9),
erlang:element(6, _record@9)}
end,
erlang:element(7, Instance),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
erlang:element(11, Instance)},
_ = (erlang:element(4, erlang:element(7, Flow)))(
erlang:element(2, Instance)
),
case erlang:element(8, Flow) of
{some, Handler} ->
case Handler(Ctx, Completed_instance) of
{ok, New_ctx} ->
case run_flow_exit_hook(
erlang:element(16, Flow),
New_ctx,
Completed_instance
) of
{ok, Final_ctx} ->
{ok, Final_ctx};
{error, Err@9} ->
handle_error(
Flow,
Ctx,
Completed_instance,
{some, Err@9}
)
end;
{error, Err@10} ->
handle_error(
Flow,
Ctx,
Completed_instance,
{some, Err@10}
)
end;
none ->
case run_flow_exit_hook(
erlang:element(16, Flow),
Ctx,
Completed_instance
) of
{ok, Final_ctx@1} ->
{ok, Final_ctx@1};
{error, Err@11} ->
handle_error(
Flow,
Ctx,
Completed_instance,
{some, Err@11}
)
end
end;
cancel ->
emit_flow_event(
<<"cancel"/utf8>>,
Instance,
[{<<"count"/utf8>>, 1}]
),
case run_flow_exit_hook(erlang:element(16, Flow), Ctx, Instance) of
{ok, Final_ctx@2} ->
_ = (erlang:element(4, erlang:element(7, Flow)))(
erlang:element(2, Instance)
),
{ok, Final_ctx@2};
{error, Err@12} ->
handle_error(Flow, Ctx, Instance, {some, Err@12})
end;
wait ->
Token = generate_wait_token(Instance),
Updated_instance@9 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
erlang:element(7, Instance),
{some, Token},
none,
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@9
) of
{ok, _} ->
{ok, Ctx};
{error, Err@13} ->
handle_error(Flow, Ctx, Instance, {some, Err@13})
end;
wait_callback ->
Token = generate_wait_token(Instance),
Updated_instance@9 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
erlang:element(7, Instance),
{some, Token},
none,
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@9
) of
{ok, _} ->
{ok, Ctx};
{error, Err@13} ->
handle_error(Flow, Ctx, Instance, {some, Err@13})
end;
{wait_with_timeout, Timeout_ms} ->
Token@1 = generate_wait_token(Instance),
Wait_timeout_at = telega@internal@utils:current_time_ms() + Timeout_ms,
Updated_instance@10 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
erlang:element(7, Instance),
{some, Token@1},
{some, Wait_timeout_at},
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@10
) of
{ok, _} ->
{ok, Ctx};
{error, Err@14} ->
handle_error(Flow, Ctx, Instance, {some, Err@14})
end;
{wait_callback_with_timeout, Timeout_ms} ->
Token@1 = generate_wait_token(Instance),
Wait_timeout_at = telega@internal@utils:current_time_ms() + Timeout_ms,
Updated_instance@10 = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
erlang:element(7, Instance),
{some, Token@1},
{some, Wait_timeout_at},
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@10
) of
{ok, _} ->
{ok, Ctx};
{error, Err@14} ->
handle_error(Flow, Ctx, Instance, {some, Err@14})
end;
{exit, _} ->
_ = (erlang:element(4, erlang:element(7, Flow)))(
erlang:element(2, Instance)
),
{ok, Ctx};
{enter_subflow, Subflow_name, Data@1} ->
case gleam@list:find(
erlang:element(13, Flow),
fun(Config) ->
erlang:element(2, erlang:element(3, Config)) =:= Subflow_name
end
) of
{ok, Subflow_config} ->
Return_step = (erlang:element(5, Flow))(
erlang:element(4, Subflow_config)
),
Stack_frame = {flow_stack_frame,
erlang:element(2, Flow),
Return_step,
erlang:element(3, erlang:element(6, Instance))},
Subflow_initial_step = (erlang:element(
5,
erlang:element(3, Subflow_config)
))(erlang:element(4, erlang:element(3, Subflow_config))),
Updated_instance@11 = {flow_instance,
erlang:element(2, Instance),
erlang:element(2, erlang:element(3, Subflow_config)),
erlang:element(4, Instance),
erlang:element(5, Instance),
{flow_state,
Subflow_initial_step,
maps:merge(
erlang:element(3, erlang:element(6, Instance)),
Data@1
),
[Subflow_initial_step],
[Stack_frame |
erlang:element(5, erlang:element(6, Instance))],
none},
maps:new(),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(
Updated_instance@11
) of
{ok, _} ->
execute_subflow_step(
erlang:element(3, Subflow_config),
Ctx,
Updated_instance@11,
Subflow_config
);
{error, Err@15} ->
handle_error(Flow, Ctx, Instance, {some, Err@15})
end;
{error, _} ->
{ok, Ctx}
end
end.
-file("src/telega/flow/engine.gleam", 283).
?DOC(" Process action with leave hook support\n").
-spec process_action_with_leave_hook(
telega@flow@types:flow(BCMI, BCMJ, BCMK, BCML),
telega@bot:context(BCMJ, BCMK, BCML),
telega@flow@types:flow_action(BCMI),
telega@flow@types:flow_instance(),
gleam@option:option(fun((telega@bot:context(BCMJ, BCMK, BCML), telega@flow@types:flow_instance()) -> {ok,
{telega@bot:context(BCMJ, BCMK, BCML),
telega@flow@types:flow_instance()}} |
{error, BCMK}))
) -> {ok, telega@bot:context(BCMJ, BCMK, BCML)} | {error, BCMK}.
process_action_with_leave_hook(Flow, Ctx, Action, Instance, Leave_hook) ->
case Action of
wait ->
process_action(Flow, Ctx, Action, Instance);
wait_callback ->
process_action(Flow, Ctx, Action, Instance);
{wait_with_timeout, _} ->
process_action(Flow, Ctx, Action, Instance);
{wait_callback_with_timeout, _} ->
process_action(Flow, Ctx, Action, Instance);
_ ->
case run_leave_hook(Leave_hook, Ctx, Instance) of
{ok, {Ctx_after_leave, Instance_after_leave}} ->
process_action(
Flow,
Ctx_after_leave,
Action,
Instance_after_leave
);
{error, Err} ->
handle_error(Flow, Ctx, Instance, {some, Err})
end
end.
-file("src/telega/flow/engine.gleam", 821).
-spec start_parallel_execution(
telega@flow@types:flow(BCSR, BCSS, BCST, BCSU),
telega@bot:context(BCSS, BCST, BCSU),
telega@flow@types:flow_instance(),
telega@flow@types:parallel_config(BCSR)
) -> {ok, telega@bot:context(BCSS, BCST, BCSU)} | {error, BCST}.
start_parallel_execution(Flow, Ctx, Instance, Config) ->
Pending_steps = gleam@list:map(
erlang:element(3, Config),
erlang:element(5, Flow)
),
Join_step = (erlang:element(5, Flow))(erlang:element(4, Config)),
Parallel_state = {parallel_state, Pending_steps, [], maps:new(), Join_step},
Updated_instance = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record = erlang:element(6, Instance),
{flow_state,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
{some, Parallel_state}}
end,
erlang:element(7, Instance),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(Updated_instance) of
{ok, _} ->
case Pending_steps of
[Current_step | _] ->
Step_instance = {flow_instance,
erlang:element(2, Updated_instance),
erlang:element(3, Updated_instance),
erlang:element(4, Updated_instance),
erlang:element(5, Updated_instance),
begin
_record@1 = erlang:element(6, Updated_instance),
{flow_state,
Current_step,
erlang:element(3, _record@1),
erlang:element(4, _record@1),
erlang:element(5, _record@1),
erlang:element(6, _record@1)}
end,
erlang:element(7, Updated_instance),
erlang:element(8, Updated_instance),
erlang:element(9, Updated_instance),
erlang:element(10, Updated_instance),
erlang:element(11, Updated_instance)},
execute_step(Flow, Ctx, Step_instance);
[] ->
{ok, Ctx}
end;
{error, Err} ->
handle_error(Flow, Ctx, Instance, {some, Err})
end.
-file("src/telega/flow/engine.gleam", 151).
?DOC(false).
-spec execute_step(
telega@flow@types:flow(any(), BCKC, BCKD, BCKE),
telega@bot:context(BCKC, BCKD, BCKE),
telega@flow@types:flow_instance()
) -> {ok, telega@bot:context(BCKC, BCKD, BCKE)} | {error, BCKD}.
execute_step(Flow, Ctx, Instance) ->
case check_conditionals(Flow, Instance) of
{some, Next_step} ->
Updated_instance = {flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
begin
_record = erlang:element(6, Instance),
{flow_state,
Next_step,
erlang:element(3, _record),
[erlang:element(2, erlang:element(6, Instance)) |
erlang:element(4, erlang:element(6, Instance))],
erlang:element(5, _record),
erlang:element(6, _record)}
end,
erlang:element(7, Instance),
erlang:element(8, Instance),
erlang:element(9, Instance),
erlang:element(10, Instance),
telega@internal@utils:current_time_ms()},
case (erlang:element(2, erlang:element(7, Flow)))(Updated_instance) of
{ok, _} ->
execute_step(Flow, Ctx, Updated_instance);
{error, Err} ->
handle_error(Flow, Ctx, Instance, {some, Err})
end;
none ->
case check_parallel_trigger(Flow, Instance) of
{some, Config} ->
start_parallel_execution(Flow, Ctx, Instance, Config);
none ->
case check_subflow_trigger(Flow, Instance) of
{some, Subflow_config} ->
start_subflow_execution(
Flow,
Ctx,
Instance,
Subflow_config
);
none ->
case gleam_stdlib:map_get(
erlang:element(3, Flow),
erlang:element(2, erlang:element(6, Instance))
) of
{ok, Config@1} ->
case run_enter_hook(
erlang:element(4, Config@1),
Ctx,
Instance
) of
{ok,
{Ctx_after_enter,
Instance_after_enter}} ->
Handler_fn = fun() ->
(erlang:element(2, Config@1))(
Ctx_after_enter,
Instance_after_enter
)
end,
Started_at = erlang:monotonic_time(),
Result = apply_middlewares(
Ctx_after_enter,
Instance_after_enter,
Handler_fn,
lists:append(
erlang:element(10, Flow),
erlang:element(3, Config@1)
)
),
emit_flow_event(
<<"step"/utf8>>,
Instance,
[{<<"duration"/utf8>>,
erlang:monotonic_time()
- Started_at}]
),
case Result of
{ok,
{New_ctx,
Action,
New_instance}} ->
process_action_with_leave_hook(
Flow,
New_ctx,
Action,
New_instance,
erlang:element(
5,
Config@1
)
);
{error, Err@1} ->
handle_error(
Flow,
Ctx,
Instance,
{some, Err@1}
)
end;
{error, Err@2} ->
handle_error(
Flow,
Ctx,
Instance,
{some, Err@2}
)
end;
{error, _} ->
handle_error(Flow, Ctx, Instance, none)
end
end
end
end.
-file("src/telega/flow/engine.gleam", 686).
-spec run_flow_enter_hook(
gleam@option:option(fun((telega@bot:context(BCOY, BCOZ, BCPA), telega@flow@types:flow_instance()) -> {ok,
{telega@bot:context(BCOY, BCOZ, BCPA),
telega@flow@types:flow_instance()}} |
{error, BCOZ})),
telega@bot:context(BCOY, BCOZ, BCPA),
telega@flow@types:flow_instance()
) -> {ok,
{telega@bot:context(BCOY, BCOZ, BCPA),
telega@flow@types:flow_instance()}} |
{error, BCOZ}.
run_flow_enter_hook(Hook, Ctx, Instance) ->
case Hook of
{some, Enter_fn} ->
Enter_fn(Ctx, Instance);
none ->
{ok, {Ctx, Instance}}
end.
-file("src/telega/flow/engine.gleam", 39).
?DOC(false).
-spec start_or_resume(
telega@flow@types:flow(any(), BCHY, BCHZ, BCIA),
telega@bot:context(BCHY, BCHZ, BCIA),
integer(),
integer(),
gleam@dict:dict(binary(), binary())
) -> {ok, telega@bot:context(BCHY, BCHZ, BCIA)} | {error, BCHZ}.
start_or_resume(Flow, Ctx, User_id, Chat_id, Initial_data) ->
Flow_id = <<<<<<<<(erlang:element(2, Flow))/binary, "_"/utf8>>/binary,
(erlang:integer_to_binary(Chat_id))/binary>>/binary,
"_"/utf8>>/binary,
(erlang:integer_to_binary(User_id))/binary>>,
case (erlang:element(3, erlang:element(7, Flow)))(Flow_id) of
{ok, {some, Existing_instance}} ->
case telega@flow@instance:is_expired(
Existing_instance,
erlang:element(17, Flow)
) of
true ->
_ = (erlang:element(4, erlang:element(7, Flow)))(
erlang:element(2, Existing_instance)
),
Initial_step_name = (erlang:element(5, Flow))(
erlang:element(4, Flow)
),
New_instance = telega@flow@instance:new_instance_with_data(
Flow_id,
erlang:element(2, Flow),
User_id,
Chat_id,
Initial_step_name,
Initial_data
),
case (erlang:element(2, erlang:element(7, Flow)))(
New_instance
) of
{ok, _} ->
case run_flow_enter_hook(
erlang:element(14, Flow),
Ctx,
New_instance
) of
{ok, {Ctx_after_enter, Instance_after_enter}} ->
execute_step(
Flow,
Ctx_after_enter,
Instance_after_enter
);
{error, Err} ->
handle_error(
Flow,
Ctx,
New_instance,
{some, Err}
)
end;
{error, Err@1} ->
handle_error(Flow, Ctx, New_instance, {some, Err@1})
end;
false ->
execute_step(Flow, Ctx, Existing_instance)
end;
{ok, none} ->
Initial_step_name@1 = (erlang:element(5, Flow))(
erlang:element(4, Flow)
),
New_instance@1 = telega@flow@instance:new_instance_with_data(
Flow_id,
erlang:element(2, Flow),
User_id,
Chat_id,
Initial_step_name@1,
Initial_data
),
case (erlang:element(2, erlang:element(7, Flow)))(New_instance@1) of
{ok, _} ->
case run_flow_enter_hook(
erlang:element(14, Flow),
Ctx,
New_instance@1
) of
{ok, {Ctx_after_enter@1, Instance_after_enter@1}} ->
execute_step(
Flow,
Ctx_after_enter@1,
Instance_after_enter@1
);
{error, Err@2} ->
handle_error(
Flow,
Ctx,
New_instance@1,
{some, Err@2}
)
end;
{error, Err@3} ->
handle_error(Flow, Ctx, New_instance@1, {some, Err@3})
end;
{error, Err@4} ->
Dummy_instance = telega@flow@instance:new_instance(
Flow_id,
erlang:element(2, Flow),
User_id,
Chat_id,
<<""/utf8>>
),
handle_error(Flow, Ctx, Dummy_instance, {some, Err@4})
end.
-file("src/telega/flow/engine.gleam", 130).
?DOC(false).
-spec resume_with_instance(
telega@flow@types:flow(any(), BCJJ, BCJK, BCJL),
telega@bot:context(BCJJ, BCJK, BCJL),
telega@flow@types:flow_instance(),
gleam@option:option(gleam@dict:dict(binary(), binary()))
) -> {ok, telega@bot:context(BCJJ, BCJK, BCJL)} | {error, BCJK}.
resume_with_instance(Flow, Ctx, Instance, Data) ->
Updated_instance = case Data of
{some, D} ->
{flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
maps:merge(erlang:element(7, Instance), D),
none,
none,
erlang:element(10, Instance),
erlang:element(11, Instance)};
none ->
{flow_instance,
erlang:element(2, Instance),
erlang:element(3, Instance),
erlang:element(4, Instance),
erlang:element(5, Instance),
erlang:element(6, Instance),
erlang:element(7, Instance),
none,
none,
erlang:element(10, Instance),
erlang:element(11, Instance)}
end,
execute_step(Flow, Ctx, Updated_instance).
-file("src/telega/flow/engine.gleam", 871).
-spec find_instance_by_token(telega@flow@types:flow_storage(BCTQ), binary()) -> {ok,
gleam@option:option(telega@flow@types:flow_instance())} |
{error, BCTQ}.
find_instance_by_token(Storage, Token) ->
case gleam@string:split(Token, <<":"/utf8>>) of
[Instance_id | _] ->
(erlang:element(3, Storage))(Instance_id);
_ ->
{ok, none}
end.
-file("src/telega/flow/engine.gleam", 116).
?DOC(false).
-spec resume_with_token(
telega@flow@types:flow(any(), BCIQ, BCIR, BCIS),
telega@bot:context(BCIQ, BCIR, BCIS),
binary(),
gleam@option:option(gleam@dict:dict(binary(), binary()))
) -> {ok, telega@bot:context(BCIQ, BCIR, BCIS)} | {error, BCIR}.
resume_with_token(Flow, Ctx, Token, Data) ->
case find_instance_by_token(erlang:element(7, Flow), Token) of
{ok, {some, Instance}} ->
resume_with_instance(Flow, Ctx, Instance, Data);
_ ->
{ok, Ctx}
end.
-file("src/telega/flow/engine.gleam", 252).
?DOC(false).
-spec extract_ids_from_context(telega@bot:context(any(), any(), any())) -> {integer(),
integer()}.
extract_ids_from_context(Ctx) ->
{erlang:element(2, erlang:element(3, Ctx)),
erlang:element(3, erlang:element(3, Ctx))}.