-module(aion@workflow@entrypoint). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/aion/workflow/entrypoint.gleam"). -export([entrypoint/2]). -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( " workflow.entrypoint: the engine-facing run adapter, assembled from a\n" " `WorkflowDefinition`'s codecs and typed entry function.\n" "\n" " The engine spawns `entry_module:entry_function/1` with one argument: a\n" " BEAM binary holding the start input's JSON text. Every workflow used to\n" " hand-write the same adapter — decode the binary to a string, decode the\n" " string with the input codec, call the typed entry function, encode the\n" " output or error back to JSON text. `entrypoint` is that adapter, built\n" " purely from the definition's own accessors, so a workflow module's engine\n" " entry collapses to one line:\n" "\n" " ```gleam\n" " pub fn run(raw_input: Dynamic) -> Result(String, String) {\n" " workflow.entrypoint(definition(), raw_input)\n" " }\n" " ```\n" "\n" " Success and typed failure are byte-identical to the hand-written adapter:\n" " `Ok` encodes with the definition's output codec, `Error` with its error\n" " codec, so an awaiting parent decodes both with the same codecs it already\n" " holds. Only the garbage-input edge has a fixed shape: when the raw payload\n" " is not a string or the input codec rejects it, the failure payload is the\n" " documented JSON envelope\n" " `{\"aion_error\":\"input_decode\",\"reason\":...,\"path\":[...]}` — the engine\n" " records it as failure details, and a parent awaiting the child surfaces it\n" " as typed error-decode data, never a crash.\n" ). -file("src/aion/workflow/entrypoint.gleam", 80). ?DOC( " The documented input-decode failure envelope:\n" " `{\"aion_error\":\"input_decode\",\"reason\":...,\"path\":[...]}`.\n" ). -spec input_decode_envelope(binary(), list(binary())) -> binary(). input_decode_envelope(Reason, Path) -> _pipe = gleam@json:object( [{<<"aion_error"/utf8>>, gleam@json:string(<<"input_decode"/utf8>>)}, {<<"reason"/utf8>>, gleam@json:string(Reason)}, {<<"path"/utf8>>, gleam@json:array(Path, fun gleam@json:string/1)}] ), gleam@json:to_string(_pipe). -file("src/aion/workflow/entrypoint.gleam", 54). ?DOC(" Decode the JSON text, run the typed entry, and encode the outcome.\n"). -spec run_typed( aion@workflow@define:workflow_definition(any(), any(), any()), binary() ) -> {ok, binary()} | {error, binary()}. run_typed(Definition, Raw_json) -> Input_codec = aion@workflow@define:input_codec(Definition), case (erlang:element(3, Input_codec))(Raw_json) of {ok, Input} -> Entry = aion@workflow@define:entry_fn(Definition), case Entry(Input) of {ok, Output} -> Output_codec = aion@workflow@define:output_codec(Definition), {ok, (erlang:element(2, Output_codec))(Output)}; {error, Workflow_error} -> Error_codec = aion@workflow@define:error_codec(Definition), {error, (erlang:element(2, Error_codec))(Workflow_error)} end; {error, {decode_error, Reason, Path}} -> {error, input_decode_envelope(Reason, Path)} end. -file("src/aion/workflow/entrypoint.gleam", 40). ?DOC( " Drive a workflow's typed entry from the engine's raw spawn argument.\n" "\n" " Decodes `raw_input` (a BEAM binary of JSON text) with the definition's\n" " input codec, invokes the typed entry function, and encodes the outcome\n" " with the definition's output or error codec. An undecodable input yields\n" " `Error` of the documented `aion_error: input_decode` JSON envelope.\n" ). -spec entrypoint( aion@workflow@define:workflow_definition(any(), any(), any()), gleam@dynamic:dynamic_() ) -> {ok, binary()} | {error, binary()}. entrypoint(Definition, Raw_input) -> case gleam@dynamic@decode:run( Raw_input, {decoder, fun gleam@dynamic@decode:decode_string/1} ) of {ok, Raw_json} -> run_typed(Definition, Raw_json); {error, _} -> {error, input_decode_envelope( <<"workflow input payload was not a string"/utf8>>, [] )} end.