Skip to main content

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.

ParameterTypeDescription
propsdictProps passed from parent or initial_props

Returns (or inferred when omitted): A mapping with keys:

  • props: merged props defaults
  • state: reactive state values
  • data: server data exposed as py.* in templates
  • actions: mapping of action names to either callables or op mappings
  • lifecycle: 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 as lifecycle

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, toggle
  • multi (list of operations)
  • log (emits browser console.log)
  • js (raw JavaScript statement)
  • set_prop (updates props payload)
  • server_call (invokes POST /__moon_spa_action)

Callable actions/lifecycle hooks are normalized into server_call operations.

Lifecycle names

Supported canonical lifecycle hooks in generated client scripts:

  • created
  • mounted
  • updated
  • unmounted

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.

FieldTypeDefaultDescription
namestrState variable name
from_propstr | NoneNoneProp name to seed from
defaultAnyNoneFallback value if prop absent
caststr"raw"Type coercion: "int", "float", "str", "bool", "raw"

ComponentDefinition

Internal dataclass representing a parsed .lspa file.

FieldTypeDescription
namestrComponent name
templatestrHTML template string
client_scriptstrCompiled setup() JS function
python_blockstrRaw <python> source
importsMapping[str, str]{alias: alias} import map