Computed
Computeds are values derived from context (or other computeds). They are lazy — only evaluated when read — and memoized — only re-evaluated when an input they actually read changes.
import { machine } from '@dunky-dev/state-machine'
const m = machine({ initial: 'idle', context: { items: ['a', 'b', 'c'] }, computed: { count: ({ context }) => context.items.length, isEmpty: ({ computed }) => computed.count === 0, // derives from another computed }, states: { idle: {} },})
m.start()m.computed.count // 3m.computed.isEmpty // falseWhere computeds are available
Section titled “Where computeds are available”A computed value is accessible anywhere context is — guards, actions, effects, watchers — via { computed } in the $ argument:
states: { idle: { on: { submit: { guard: ({ computed }) => !computed.isEmpty, actions: ({ computed }) => console.log('items:', computed.count), }, }, },}Derived lists
Section titled “Derived lists”The classic use case: filter or derive a list from context fields rather than keeping a parallel list in state.
const m = machine({ initial: 'idle', context: { query: '', items: ALL_ITEMS, activeIndex: -1 }, computed: { filtered: $ => $.context.items.filter(i => i.label.includes($.context.query)), highlighted: $ => $.computed.filtered[$.context.activeIndex] ?? null, }, states: { idle: {} },})filtered only recomputes when query or items changes. highlighted only recomputes when filtered or activeIndex changes. The memoization is automatic — no useMemo, no manual deps.