telega/dialog/engine

Compiles a Dialog into a Flow(String, ...) and dispatches events.

Each window becomes a flow step (step type = the window id). The step handler runs the render → wait → dispatch cycle:

The engine is type-erased: telega/dialog.build() wraps every user-typed window into a Window(String, ...) whose closures carry the dialog’s own state codec, so the engine only ever moves the encoded state string around. This is what lets a sub-dialog with a different state type live inside its parent’s flow.

Sub-dialogs

Sub-dialogs deliberately do NOT use the flow engine’s EnterSubflow/FlowStackFrame machinery: that path never re-executes the parent step after the sub-flow returns (and sets no wait token, so auto-resume cannot wake it), resumes sub-flow steps against the parent’s step registry, and loses the parent’s history. Instead the sub-dialog’s windows are compiled into the parent flow as <sub_id>.<window_id> steps and the engine keeps its own return bookkeeping in instance data:

keycontent
__dialog_subactive sub-dialog id (absent at top level)
__dialog_return_windowparent window that emitted StartSub
__dialog_sub_savedparent’s encoded state while the sub runs

The live message, its kind, waits, TTL and persistence are shared with the parent for free (same instance). A Back that would cross the sub boundary cancels the sub and returns to the parent window without calling on_sub_result.

Navigation deliberately never uses the flow GoTo action — it erases history, which would break Back. Only Next/NextString/Back are emitted, plus the history-preserving Jump for sub-dialog enter/return (which must not push sub steps onto the parent history).

Types

Everything the engine needs to know about a dialog, with all window handlers erased to the encoded-state form. Built by telega/dialog.build(); not constructed by hand.

pub type CompiledDialog(session, error, dependencies) {
  CompiledDialog(
    id: String,
    windows: dict.Dict(
      String,
      types.Window(String, session, error, dependencies),
    ),
    initial: String,
    initial_encoded: fn() -> String,
    on_done: option.Option(
      fn(String, bot.Context(session, error, dependencies)) -> Result(
        bot.Context(session, error, dependencies),
        error,
      ),
    ),
    subs: dict.Dict(String, CompiledSub),
    storage: types.FlowStorage(error),
    ttl_ms: option.Option(Int),
    labels: fn(bot.Context(session, error, dependencies)) -> types.Labels,
  )
}

Constructors

A sub-dialog attachment: how to build its starting state and how to turn its final state into the result dict for on_sub_result.

pub type CompiledSub {
  CompiledSub(
    id: String,
    initial: String,
    init: fn(String, dict.Dict(String, String)) -> String,
    result: fn(String) -> dict.Dict(String, String),
  )
}

Constructors

  • CompiledSub(
      id: String,
      initial: String,
      init: fn(String, dict.Dict(String, String)) -> String,
      result: fn(String) -> dict.Dict(String, String),
    )

    Arguments

    initial

    Namespaced id of the sub-dialog’s initial window.

    init

    fn(parent_encoded_state, args) -> sub_encoded_state

    result

    fn(sub_encoded_state) -> result dict

Values

pub fn compile(
  dialog: CompiledDialog(session, error, dependencies),
) -> types.Flow(String, session, error, dependencies)

Compile a dialog into a flow. Window id = step name (identity converters), on_error is always set (the flow engine silently swallows errors otherwise): it logs, emits telemetry, and re-renders the current window best-effort.

pub const flow_name_prefix: String

Flow names are prefixed so dialogs never collide with hand-written flows in the same registry.

pub fn parse_callback_data(
  data: String,
) -> Result(#(String, String, types.ActionEvent), Nil)

Parse dlg:<dialog_id>:<window_id>:<action_id>[:<arg>]. Extra segments are joined back into the arg, so args may contain :.

pub const sub_separator: String

Separator between a sub-dialog id and its window ids in step names and callback data (address.city). Forbidden in dialog/window/sub ids.

Search Document