Where documents live (spec/03 §1): the store behavior, the assign's functions, typed ids (§2) and import as a relocation (§3.3).
A store holds entries, %{id, name, fragment}, of the fragment types it was given
(spec/02 §1). An entry's kind is derived from its fragment, never stored; its name is an
attribute, never an identity. A store is reached through an assign, {module, context} or a bare module, so every call carries who is acting and from where.
Store.put({Macaw.Layers.Store.Memory, agent}, %{id: nil, name: "Styles:thick", fragment: %{style: %{width: 3}}})
#=> {:ok, {:style, 1}}Ported from visualize's Visualize.Chart.Builder.Store, its callbacks answering {:ok, …}
or {:error, …} as every Macaw contract does.
Summary
Types
A store's module and its context, or a bare module, whose context is nil.
A stored fragment: its id, nil before the store issues one, and its name.
An id: a kind of the store's types and a positive integer the store issued.
What an import answers: the old => new table, and each reference outside the bundle.
What a picker lists.
Callbacks
An entry removed.
The entry of an id.
A bundle relocated into the store, whole or not at all (§3.3).
Every entry's summary.
An entry stored: a new id issued to one without, a held one replaced.
The fragment types the store holds.
Functions
The types, checked when a store is configured: each a fragment type, and no kind
declared by two of them. Raises ArgumentError naming both types and the kind.
The id a string spells, its kind matched against kinds by its string, so no atom is
made from a client's string: {:ok, id} or :error.
An entry removed.
An id as one string, for the DOM and the wire.
The entry of an id.
A name's filing, <group>:<sub-group>:<name>: the segments before the last, empty ones
dropped, and the last. Nothing references it.
A bundle imported.
{type, kind} of the first of the store's types that derives the fragment a kind
(spec/02 §6.1), or nil: a fragment about more than one thing is not storable.
Every kind of the store's types (an assign, or the types themselves), sorted.
Every entry's summary.
An entry stored.
A reference held to the kind its site takes, before it is resolved (§2): :ok, or
{:error, {:ref_kind, wanted, given}} for an id of another kind, for a type's reader to
report at the site's path.
A bundle imported through the store's own put/2 (§3.3): every check first, then new
ids issued, then every reference rewritten through one table and each entry put again.
The assign as {module, context}; a bare module has a nil context.
The type a kind belongs to, or nil.
The store's types.
Types
A store's module and its context, or a bare module, whose context is nil.
A stored fragment: its id, nil before the store issues one, and its name.
@type id() :: {atom(), pos_integer()}
An id: a kind of the store's types and a positive integer the store issued.
@type imported() :: %{ ids: %{required(id()) => id()}, outside: [{id(), Macaw.Layers.Fault.path()}] }
What an import answers: the old => new table, and each reference outside the bundle.
What a picker lists.
Callbacks
An entry removed.
The entry of an id.
@callback import(Macaw.Layers.Bundle.t(), context :: term()) :: {:ok, imported()} | {:error, [Macaw.Layers.Fault.t(), ...]}
A bundle relocated into the store, whole or not at all (§3.3).
Every entry's summary.
An entry stored: a new id issued to one without, a held one replaced.
The fragment types the store holds.
Functions
The types, checked when a store is configured: each a fragment type, and no kind
declared by two of them. Raises ArgumentError naming both types and the kind.
The id a string spells, its kind matched against kinds by its string, so no atom is
made from a client's string: {:ok, id} or :error.
iex> Macaw.Layers.Store.decode_id([:style, :mark], "style:11")
{:ok, {:style, 11}}
iex> Macaw.Layers.Store.decode_id([:style, :mark], "widget:11")
:error
An entry removed.
An id as one string, for the DOM and the wire.
iex> Macaw.Layers.Store.encode_id({:style, 11})
"style:11"
The entry of an id.
A name's filing, <group>:<sub-group>:<name>: the segments before the last, empty ones
dropped, and the last. Nothing references it.
iex> Macaw.Layers.Store.group("Styles::thick")
{["Styles"], "thick"}
@spec import(assign(), Macaw.Layers.Bundle.t()) :: {:ok, imported()} | {:error, [Macaw.Layers.Fault.t(), ...]}
A bundle imported.
{type, kind} of the first of the store's types that derives the fragment a kind
(spec/02 §6.1), or nil: a fragment about more than one thing is not storable.
Every kind of the store's types (an assign, or the types themselves), sorted.
Every entry's summary.
An entry stored.
A reference held to the kind its site takes, before it is resolved (§2): :ok, or
{:error, {:ref_kind, wanted, given}} for an id of another kind, for a type's reader to
report at the site's path.
@spec relocate(assign(), Macaw.Layers.Bundle.t(), keyword()) :: {:ok, imported()} | {:error, [Macaw.Layers.Fault.t(), ...]}
A bundle imported through the store's own put/2 (§3.3): every check first, then new
ids issued, then every reference rewritten through one table and each entry put again.
The checks: the bundle read again through its forms (Macaw.Layers.Bundle), so its
version and every fragment go through their readers, and the host's check: over each
entry. A fault anywhere writes nothing; every fault is reported at [:entries, i | path].
check:—(entry -> :ok | {:error, [fault]}), the host's own check, such as names its registry does not know;transaction:— a function givenrun, which it calls asrun.(state, put)inside its own transaction,put.(entry, state)answering{:ok, id, state}or{:error, reason};runanswers{:ok, imported, state}or{:error, faults}, and the transaction function{:ok, imported}or{:error, faults}, committing only the first. Without it, entries are written through the store'sput/2, which is whole only where those writes cannot fail.
A reference to an id outside the bundle is left as it is and reported in outside by the
entry that holds it: it resolves as a mask (spec/02 §7).
The assign as {module, context}; a bare module has a nil context.
The type a kind belongs to, or nil.
The store's types.