Component API
Types and base classes used when writing .lspa component Python blocks.
Class diagram
Component
Base class for all components. Available as Component in every <python> block (no import needed).
class MyComponent(Component):
def setup(self, props):
props = {"title": "Default", **props}
state = {"count": 0}
data = {"headline": "hello"}
def inc():
state["count"] += 1
def mounted():
inc()
return {
"props": props,
"state": state,
"data": data,
"actions": {"inc": inc},
"lifecycle": {"mounted": mounted},
}
setup(self, props) → dict | None
Called whenever the component is prepared for rendering/hydration. This is the only supported component contract.
| Parameter | Type | Description |
|---|---|---|
props | dict | Props passed from parent or initial_props |
Returns (or inferred when omitted): A mapping with keys:
props: merged props defaultsstate: reactive state valuesdata: server data exposed aspy.*in templatesactions: mapping of action names to either callables or op mappingslifecycle: mapping of lifecycle hook names to callables/strings/mappings/lists
If setup returns None, the server infers the mapping automatically from:
- local variables:
props,state,data - local callables inferred as
actions - lifecycle-named callables (
created,mounted,updated,unmounted) inferred aslifecycle
When actions/lifecycle mutate data, those data keys are automatically emitted in the props patch even without returning a mapping from the action.
Action operations
Declarative action mappings support these operations:
set,add,sub,togglemulti(list of operations)log(emits browserconsole.log)js(raw JavaScript statement)set_prop(updatespropspayload)server_call(invokesPOST /__moon_spa_action)
Callable actions/lifecycle hooks are normalized into server_call operations.
Lifecycle names
Supported canonical lifecycle hooks in generated client scripts:
createdmountedupdatedunmounted
Use these names exactly in setup().lifecycle.
StateField
Declarative state field metadata. Use as class/object attributes when state should be seeded from a prop.
from moon_spa.types import StateField
class Example(Component):
def setup(self, props):
state = {"count": 0}
return {
"props": props,
"state": state,
"data": {},
"actions": {},
"lifecycle": {},
}
StateField is supported by the runtime type system and normalization helpers.
Use it when you need explicit metadata such as from_prop, default, and cast.
| Field | Type | Default | Description |
|---|---|---|---|
name | str | — | State variable name |
from_prop | str | None | None | Prop name to seed from |
default | Any | None | Fallback value if prop absent |
cast | str | "raw" | Type coercion: "int", "float", "str", "bool", "raw" |
ComponentDefinition
Internal dataclass representing a parsed .lspa file.
| Field | Type | Description |
|---|---|---|
name | str | Component name |
template | str | HTML template string |
client_script | str | Compiled setup() JS function |
python_block | str | Raw <python> source |
imports | Mapping[str, str] | {alias: alias} import map |