Frontend DSL Reference¶
This page documents the YAML format for all four frontend graph types.
Directory Structure¶
Each domain (logical section of the app) has a directory with four subdirectories:
graph/
dashboard/
ui/
Dashboard/
dashboard_node.yaml
dashboard_view.tsx
ChartHeader/
header_node.yaml
header_view.tsx
state/
FilterState/
state.yaml
interface.ts
mutations.ts
ChartState/
state.yaml
interface.ts
effects/
fetch_chart_data/
effect.yaml
handler.ts
events/
refresh_chart.yaml
export_chart.yaml
UI Node YAML¶
component: Dashboard
view: dashboard_view
reads:
- FilterState.dateRange
- FilterState.region
- ChartState.series
- ChartState.loading
events:
refresh: refresh_chart_event
export: export_chart_event
children:
- ChartHeader
- ChartCanvas
- ChartLegend
props:
variant: full
Fields¶
| Field | Required | Type | Description |
|---|---|---|---|
component |
Yes | str |
Component name (PascalCase) |
view |
Yes | str |
View function/file identifier |
reads |
No | list[str] |
State field subscriptions (StateName.fieldName) |
events |
No | dict[str, str] |
Event bindings: {action: event_name} |
children |
No | list[str] |
Child component names |
props |
No | dict[str, str] |
Static properties |
Naming Convention¶
- Component names: PascalCase (e.g.,
Dashboard,ChartHeader) - View identifiers: snake_case (e.g.,
dashboard_view)
State Node YAML¶
state: FilterState
interface: FilterStateData
fields:
dateRange: DateRange
region: string
category: string
mutations:
- set_date_range
- set_region
- set_category
- reset_filters
triggers:
- fetch_chart_data
- update_url_params
initial:
dateRange: '{ start: null, end: null }'
region: '"all"'
category: '"all"'
Fields¶
| Field | Required | Type | Description |
|---|---|---|---|
state |
Yes | str |
State node name (PascalCase + "State") |
interface |
Yes | str |
TypeScript interface name |
fields |
Yes | dict[str, str] |
Field names → TypeScript types |
mutations |
Yes | list[str] |
Named mutation operations |
triggers |
No | list[str] |
Effects triggered on state change |
initial |
No | dict[str, str] |
Default values (quoted strings) |
Field Types¶
Field types are TypeScript types:
fields:
count: number
name: string
active: boolean
items: Item[]
config: Record<string, unknown>
dateRange: DateRange # Custom interface
Initial Values¶
Initial values are string representations of TypeScript values. Quote strings within the YAML:
initial:
region: '"all"' # string literal
count: '0' # number
active: 'true' # boolean
items: '[]' # empty array
dateRange: '{ start: null, end: null }' # object literal
Effect YAML¶
effect: fetch_chart_data
watch:
- FilterState.dateRange
- FilterState.region
on_event:
- chart_refresh_clicked
handler: handlers/fetch_chart_data
effect_type: side_effect
mutates:
- ChartState
- NotificationState
debounce_ms: 300
Fields¶
| Field | Required | Type | Description |
|---|---|---|---|
effect |
Yes | str |
Effect identifier |
watch |
No | list[str] |
State fields that trigger this effect |
on_event |
No | list[str] |
Events that trigger this effect |
handler |
Yes | str |
Path to handler implementation |
effect_type |
Yes | str |
"side_effect" or "derived" |
mutates |
No | list[str] |
State nodes this effect can write to |
debounce_ms |
No | int |
Milliseconds to debounce |
Note
At least one of watch or on_event must be provided. An effect with neither has no trigger and will never execute.
Effect Types¶
side_effect— Performs external operations (API calls, analytics, localStorage). Separated from state computation.derived— Computes new state from existing state. Like a computed property, declared explicitly.
Event YAML¶
event: refresh_chart_event
flow:
- ChartState.set_loading
- FilterState.reset_filters
source: ChartHeader
guards:
- is_not_loading
- is_authenticated
Fields¶
| Field | Required | Type | Description |
|---|---|---|---|
event |
Yes | str |
Event identifier |
flow |
Yes | list[str] |
Ordered mutation sequence |
source |
No | str |
Component that emits this event |
guards |
No | list[str] |
Preconditions for execution |
Flow Items¶
Each item in flow is either:
- A mutation:
StateName.mutation_name(e.g.,ChartState.set_loading) - An effect trigger:
effect_name(e.g.,fetch_chart_data)
Items execute in the declared order.
Cross-Graph References¶
The four graphs reference each other through consistent naming:
UI reads → State fields (e.g., "FilterState.dateRange")
UI emits → Events (e.g., "refresh_chart_event")
Events dispatch → Mutations (e.g., "FilterState.reset_filters")
State triggers → Effects (e.g., "fetch_chart_data")
Effects watch → State fields (e.g., "FilterState.region")
Effects mutate → State nodes (e.g., "ChartState")
All references use the format NodeName.field_or_mutation where applicable. Validation checks that all cross-references resolve to actual nodes and fields.
Loading From Disk¶
from honey_badgeria.front.dsl import (
load_ui_graph,
load_state_graph,
load_effect_graph,
load_event_graph,
)
from honey_badgeria.front.graph import FrontendDomain
ui = load_ui_graph("graph/dashboard/ui/")
state = load_state_graph("graph/dashboard/state/")
effects = load_effect_graph("graph/dashboard/effects/")
events = load_event_graph("graph/dashboard/events/")
domain = FrontendDomain("dashboard", ui, state, effects, events)