Statifier.Send.Types (Statifier v2.6.0)

Copy Markdown View Source

A caller-declared, point-in-time claim about which <send type> values this deployment's Event I/O Processors implement beyond the built-in SCXML processor (ADR-0069 decision 2) - the <send> counterpart of Statifier.Invoke.Types, in the same shape and the same posture.

This is a claim, not an observation: it is stamped once per session via Statifier.MachineState.new/2's :send_types option (or Statifier.MachineState.put_send_types/2 after a resume), fixed for the session's lifetime, and carries no obligation to track anything between writes.

The module holds the two things ADR-0069 asks to exist exactly once:

Beside the set, a registered set carries each type's _ioprocessors entry (spec 5.10), the value its processor supplies through the optional Statifier.Send.Processor.ioprocessors_entry/1 callback, so Statifier.MachineState.new/2 can write the entries from the same stamp it classifies against.

unsupported_sends/2 is the pure pre-start check of ADR-0069 decision 3. It lives here rather than in Statifier.Validator, because Statifier.Validator.validate/3 judges a document against the spec and takes no deployment state, while this check is a question about a deployment's registered set.

Summary

Types

What classify/2 answers for one resolved <send type>

t()

One <send> the pre-start check reports: its literal type and its element location.

Functions

Classifies a resolved <send type> against types (see class/0).

Builds the registered set from a :send_types map (%{type_string => module}), derived from the map's own keys rather than declared beside it - the <send> counterpart of Statifier.Invoke.Types.from_handlers/1.

The pre-start check of ADR-0069 decision 3: every <send> in machine whose literal type attribute classify/2 answers :unsupported for against types, with the <send> element's location, in c_index order.

Types

class()

@type class() :: :built_in | :registered | :unsupported

What classify/2 answers for one resolved <send type>:

  • :built_in - absent, "scxml", or the SCXML Event I/O Processor URI; the target is C.1's vocabulary and the library delivers it.
  • :registered - a type in the declared set; the target is the processor's opaque route string and is never parsed.
  • :unsupported - anything else; 6.2.5's error.execution.

t()

@type t() :: %Statifier.Send.Types{
  entries: %{required(String.t()) => map()},
  types: MapSet.t(String.t())
}

unsupported_send()

@type unsupported_send() :: %{
  type: String.t(),
  location: Statifier.Parser.Location.t()
}

One <send> the pre-start check reports: its literal type and its element location.

Functions

classify(types, type)

@spec classify(types :: t() | nil, type :: term()) :: class()

Classifies a resolved <send type> against types (see class/0).

A built-in spelling is :built_in whatever types holds, so the built-in processor keeps its targets. nil for types means "no declaration": the built-in set only, which is 6.2.5's closed set as it stood before ADR-0069 - every non-built-in type is :unsupported.

from_send_types(send_types)

@spec from_send_types(send_types :: %{optional(String.t()) => module()}) :: t() | nil

Builds the registered set from a :send_types map (%{type_string => module}), derived from the map's own keys rather than declared beside it - the <send> counterpart of Statifier.Invoke.Types.from_handlers/1.

An empty map returns nil, "no declaration": classify/2 answers the same for nil and for an empty set, and nil is what a session started without :send_types has always carried, so a host that registers nothing sees nothing change.

This is the only derivation of a registered send-type set in the library. It does not refuse a built-in spelling; Statifier.Session.start_link/2 does, and classify/2 answers :built_in for a built-in spelling whatever the set holds.

entries holds each type's _ioprocessors value: what the type's module returns from Statifier.Send.Processor.ioprocessors_entry/1, or an empty map when the module does not export it. Raises ArgumentError when a returned value is not a map, or holds an atom key other than true or false at any level, because every datamodel key is a string. Statifier.Evaluator.SystemVariables.initial/3 says when the entries are written and how they read after a resume.

unsupported_sends(machine, types)

@spec unsupported_sends(machine :: Statifier.Machine.t(), types :: t() | nil) :: [
  unsupported_send()
]

The pre-start check of ADR-0069 decision 3: every <send> in machine whose literal type attribute classify/2 answers :unsupported for against types, with the <send> element's location, in c_index order.

Pure and total. A host calls it with a compiled chart and the set it will start the chart with (from_send_types/1 of its :send_types map), and may refuse to start or activate a chart that names a processor it never registered. It cannot see a typeexpr: a type resolved at evaluation time is judged by the core's own check alone, which stays the backstop for both.