MishkaCmsCore.Runtime.Resources.Validations.StatefulShape (Mishka CMS Core v0.0.1)

Copy Markdown View Source

Refuses a component that says it keeps state and is shaped so that it cannot.

Two combinations, both of which compiled quietly before this and failed later somewhere the author could not connect to what they did.

Declaring a name LiveView owns

Phoenix.Component.assign/3 and assign_new/3 refuse five names on a socket: its @non_assignables, [:uploads, :streams, :socket, :myself], and :flash, which validate_assign_key!/1 refuses in a clause of its own. Neither is exported, so nothing can consult them; the names are repeated here, which is a copy and is why it is short and named. It is the ONLY copy: MishkaCmsCore.UiKit.Contract and the component compiler read it through reserved_names/0, so the three refusals cannot drift apart.

A function component may declare an attr called socket and get away with it because nothing ever assigns one; a live component cannot, and the failure arrives inside a visitor's LiveView rather than at the point of writing. A SLOT is the same question: the compiler's update_many/1 assigns a declared slot onto the socket under its name exactly as it assigns an attr, so slot :streams raises the moment a parent fills it.

Consequence worth stating: chelekom-file-field declares attr :uploads and therefore cannot be stateful — which is correct anyway, since allow_upload/3 is a Phoenix.LiveView function a LiveComponent cannot call.

Carrying extra.clauses

34 of the kit's installed components dispatch through extra.clauses, which compile to a case where each branch has its own root element. A stateful component has to have ONE static root — the diff raises otherwise — and the compiler's stateful emitter reads the template and not the clause list, so before this the clauses were silently discarded: a component that rendered only its base branch, with nothing said anywhere.

Refusing is the honest half of that. The other half is that a single root cannot be proven from a clause list, only from a render, which is MishkaCmsCore.Runtime.Compilers.ComponentCompiler's root probe.

Only what this write changed

A component that was stateless and is being made stateful is checked; one whose stateful is not changing and whose declarations are not changing is left alone, so a row stored before this validation existed stays editable.

Summary

Functions

The names a live component cannot declare, as an attr or as a slot, because LiveView assigns them itself.

Functions

reserved_names()

@spec reserved_names() :: [String.t()]

The names a live component cannot declare, as an attr or as a slot, because LiveView assigns them itself.