The state block and defchange: §3's change derivation, in Elixir.
Declared state is mutated only through declared changes, because the change
log IS how a cell is rebuilt. A state block declares the fields and their
defaults, and defchange writes each change once:
use Flezha.SDK.Tasklet, name: "position"
state do
field :qty, :integer, default: 0
field :fill_ids, :list, default: []
end
defchange record_fill(state, qty, id) do
%{state | qty: state.qty + qty, fill_ids: [id | state.fill_ids]}
endThe block generates init_state/1 (the map of defaults, overridable) and
state_from_json/1 (each field read by its string key, falling back to its
default). It generates no change.
defchange name(state, args…) do body end is the one way to change state,
in a module with or without a block: it is written once and generated into
both halves — the apply_change(state, {:name, args…}) clause and the
recorder name(state, ctx, args…), which journals the change through
Flezha.SDK.Ctx.apply/3 and answers the new state — so a mutation spanning
several fields is one journal record. A module with no defchange exports
no apply_change/2 and is changeless.
A module that uses Flezha.SDK.Tasklet or a relay macro and writes
apply_change/2 by hand fails to compile, directing the author to
defchange; a hand-written apply_change/2 belongs to the reference form,
@behaviour Flezha.SDK.Tasklet. A block beside a hand-written
state_from_json/1 fails to compile too: the block owns it.
§3.1's keyed-map and deque modes are deferred for Elixir; this block carries
the field and :list modes only. Renaming or retyping a field is a
non-additive state edit and takes a schema-version bump, as §3.0 says for
every SDK.
Summary
Functions
A hand-written change: one body, generated into the fold and the recorder, so a mutation spanning several fields is one journal record.
One state field: a name, one of :integer, :float, :string, :boolean,
:list, :map or :term, and a default:.
Declare the fields a cell's state carries. See the module doc.
Functions
A hand-written change: one body, generated into the fold and the recorder, so a mutation spanning several fields is one journal record.
One state field: a name, one of :integer, :float, :string, :boolean,
:list, :map or :term, and a default:.
Declare the fields a cell's state carries. See the module doc.