Example: Counter
The smallest complete QORM app — global state, an action, and a binding. Source: examples/counter.
qorm run examples/counter
Press + / -: the button dispatches an action, the runtime updates state, and the bound text re-renders.
The pieces
Global state, declared in qorm.json:
"globalState": { "schema": { "count": "number" }, "initial": { "count": 0 } }
The count, bound in the scene:
{ "type": "text", "id": "number", "text": "{{state.count}}" }
A button invokes an action, passing the current value as an argument:
{ "type": "button", "id": "btn_plus", "label": "+",
"onPress": { "type": "invoke", "name": "increment", "args": { "count": "{{state.count}}" } } }
The action (actions/increment.json) computes the new value:
{ "type": "action", "id": "increment",
"steps": [ { "type": "state.set", "path": "count", "value": "{{ count + 1 }}" } ] }
Format notes (this is the runnable format)
- Text is the
textfield (notvalue); bind with{{ state.x }}. - A button's callback is
onPress(noton: { press }), naming an action. - Inside the action,
valuesees the args fromonPress(herecount), so
{{ count + 1 }} works. (You can also read global state directly — {{ state.count + 1 }} — as the getting-started tutorial does; the arg form here shows how onPress args come through.) The [JSON format spec] design-intent draft diverges — trust the examples.