You can call factories to create actions for you. These actions will help you change state and control the flow of execution.
Read more about factories in the the guide article.
The methods for changing state within actions are also available as factories.
All store are imported as members of the ‘cerebral/factories’ module. For example:
import { set } from 'cerebral/factories'
Concatenate a value to an array
concat(state`some.list`, ['foo', 'bar'])
Increment an integer value by another integer value into an array. The default increment is 1, and a negative value effectively does a decrement.
increment(state`some.integer`)
increment(state`some.integer`, -5)
increment(state`some.integer`, state`some.otherInteger`)
increment(state`some.integer`, props`some.otherInteger`)
Merge objects into existing value. If no value exists, an empty object will be created. Merge supports using operator tags on key values:
merge(state`clients.$draft`, props`newDraft`, {
foo: 'bar',
bar: props`baz`
})
Pop a value off an array (removes last element from array).
pop(state`some.list`)
Push value into an array (adds the element at the end of the array).
push(state`some.list`, 'foo')
Set a target value in the state or props.
set(state`foo.bar`, true)
set(props`foo`, true)
Optionally transform the value before setting
set(state`some.number`, props`number`, (value) => value * 2)
Shift a value off an array (removes first element in array).
shift(state`some.list`),
Splice an array in place.
splice(state`some.list`, 0, 2)
Toggle a boolean value.
toggle(state`user.$toolbar`)
Unset key from object.
unset(state`clients.all.${props`key`}`)
Unshift a value into an array (adds the element at the start of the array).
unshift(state`some.list`, 'foo')
These factories help control the execution flow.
Hold action until the given amount of time in milliseconds has passed. If the
sequence triggers again within this time frame, the previous sequence goes down the
“discard” path while the new sequence holds for the given time. This is
typically used for typeahead functionality. For a debounce that is shared
across different signals, you can use debounce.shared()
(see example below).
Please note that the discard
path has to be present even if it is most often
empty.
import { debounce } from 'cerebral/factories'
export default [
debounce(200),
{
continue: runThisActionOrSequence,
discard: []
}
]
debounce.shared()
is typically used with factories, for example to show
notifications where a previous notification should be cancelled by a new one.
import { debounce, set, unset } from 'cerebral/factories'
import { state } from 'cerebral'
const sharedDebounce = debounce.shared()
function showNotificationFactory(message, ms) {
return [
set(state.notification, message),
sharedDebounce(ms),
{
continue: unset(state.notification),
discard: []
}
]
}
Now when this notification factory is used in different sequence, the call to
debounceShared
will share the same debounce execution state:
import * as factories from './factories'
export default factories.showNotification('User logged in', 5000)
This operator chooses a specific path based on the provided value.
import { equals } from 'cerebral/factories'
import { state } from 'cerebral'
export default [
equals(state`user.role`), {
admin: [],
user: [],
otherwise: [] // When no match
}
],
Wait for the given time in milliseconds and then continue chain.
import { wait } from 'cerebral/factories'
export default [
wait(200),
doSomethingAfterWaiting
]
If you need to wait while executing in parallel, you should use a continue
path to isolate the sequence to be run:
import { wait } from 'cerebral/factories'
import { parallel } from 'cerebral'
export default
someAction,
parallel('my parallel with wait', [
wait(200), {
continue: [doSomethingAfterWaiting]
},
otherActionInParallel
])
]
Run signal path depending on a truth value or function evaluation.
import { when } from 'cerebral/factories'
import { state } from 'cerebral'
export default [
when(state`foo.isAwesome`),
{
true: [],
false: []
},
// You can also pass your own function
when(state`foo.isAwesome`, (value) => value.length === 3),
{
true: [],
false: []
}
]
When used with a truth function, the when
operator supports more then a single
“value” argument. The predicate function must come last.
import { when } from 'cerebral/factories'
import { props, state } from 'cerebral'
export default [
when(
state`clients.$draft.key`,
props`key`,
(draftKey, updatedKey) => draftKey === updatedKey
),
{
true: set(state`clients.$draft`, props`value`),
false: []
}
]