Flezha.SDK.State (flezha_sdk v0.1.0)

Copy Markdown View Source

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]}
end

The 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

defchange(arg, list)

(macro)

A hand-written change: one body, generated into the fold and the recorder, so a mutation spanning several fields is one journal record.

field(name, type, opts)

(macro)

One state field: a name, one of :integer, :float, :string, :boolean, :list, :map or :term, and a default:.

state(list)

(macro)

Declare the fields a cell's state carries. See the module doc.