Skip to main content

MachineStore

Extends Store. injectMachineStore() returns an instance of this class.

This class controls the store's state shape and exposes simple methods for working with the state machine. It is recommended to only use these methods to manipulate the state of the store, rather than using machineStore.setState() or machineStore.setStateDeep(). You can dispatch actions to the store via machineStore.dispatch(), but the only use for that is to use the store as a message bus.

These state machines have relative type safety. Type generics must be passed manually for full TS support, so it's recommended to use a higher-level factory (like injectMachineStore()) that does that for you to instantiate this class.

tip

MachineStore state machines are very simple. We're probably not going to support any advanced state machine features. Use XState or a similar lib if more power is needed.

State Shape

All machine stores store an object with the following properties:

{ context, value }

context can be either undefined or an object containing anything. This object is used to hold extra state related to the state machine.

value is a string. This is the actual state the machine is currently in.

Creation

Create using injectMachineStore(). It is so not recommended to instantiate this class yourself that we're not even documenting it here 😛

Methods

getContext

Returns the current state of the machine store's .context property.

// these 2 lines are equivalent:
machineStore.getContext()
machineStore.getState().context
getValue

Returns the string state that the machine is currently in. This is the value of the machine store's .value property.

// these 2 lines are equivalent:
machineStore.getValue()
machineStore.getState().value
is

Checks if the machine store's current .value matches a given string

Signature:

is = (stateName) => boolean

Accepts a single string and returns true if the machine store is currently in that state.

// these 2 lines are equivalent:
machineStore.getValue() === 'some-state'
machineStore.is('some-state')
send

This is how you transition the machine to a new state.

Signature:

send = (eventName, meta?) => newState
eventName
Required. A string. This must be one of the recognized event names of the store.
meta
Optional. Can be anything, including the special ignore meta type.
Returns
The new state of the store (an object with context and value properties), or the existing state if there was no valid transition for the passed event.
setContext

Replaces the .context of the store with the passed object.

Signature:

setContext = (contextOrFactory, meta?) => newState
contextOrFactory
Either the new context or a function that accepts the current context and returns a new context object.
meta
Optional. Can be anything, including the special ignore meta type.
Returns
The new state of the store (an object with context and value properties).

Examples:

// these 2 lines are equivalent:
machineStore.setState(state => ({ ...state, context: { key: 'val' } }))
machineStore.setContext({ key: 'val' })
// and these 2 lines are equivalent:
machineStore.setState(state => ({ ...state, context: { ...state.context, key: 'val' } }))
machineStore.setContext(context => ({ ...context, key: 'val' }))
setContextDeep

Deeply merges an object into the existing .context of the store.

This cannot be used to delete keys, only to add/update. Use .setContext() to delete.

Signature:

setContextDeep = (contextOrFactory, meta?) => newState
contextOrFactory
Either the new deep-partial context or a function that accepts the current context and returns a deep-partial context object.
meta
Optional. Can be anything, including the special ignore meta type.
Returns
The new state of the store (an object with context and value properties).

Examples:

// these 2 lines are equivalent:
machineStore.setStateDeep({ context: { key: 'val' } })
machineStore.setContextDeep({ key: 'val' })
// and these 2 lines are equivalent:
machineStore.setStateDeep(state => ({ context: { key: state.key + 1 } }))
machineStore.setContext(context => ({ key: state.key + 1 }))

See Also