From 53f338000f222a8e00497b407a6b619ce5c26950 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Fri, 4 Oct 2019 13:23:38 -0400 Subject: [PATCH] feat(@xstate/fsm): execute actions --- packages/xstate-fsm/README.md | 2 ++ packages/xstate-fsm/src/index.ts | 13 +++++++++--- packages/xstate-fsm/test/fsm.test.ts | 31 ++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/packages/xstate-fsm/README.md b/packages/xstate-fsm/README.md index 75a709d709..c8c89cffbb 100644 --- a/packages/xstate-fsm/README.md +++ b/packages/xstate-fsm/README.md @@ -213,6 +213,8 @@ An object that represents the state of a machine with the following schema: Creates an instance of an interpreted machine, also known as a **service**. This is a stateful representation of the running machine, which you can subscribe to, send events to, start, and stop. +Actions will also be executed by the interpreter. + | Argument | Type | Description | | --------- | ------------ | ------------------------------ | | `machine` | StateMachine | The machine to be interpreted. | diff --git a/packages/xstate-fsm/src/index.ts b/packages/xstate-fsm/src/index.ts index 3901f79d3f..0924e13c65 100644 --- a/packages/xstate-fsm/src/index.ts +++ b/packages/xstate-fsm/src/index.ts @@ -36,6 +36,12 @@ function createMatcher(value) { return stateValue => value === stateValue; } +function toEventObject( + event: TEvent['type'] | TEvent +): TEvent { + return (typeof event === 'string' ? { type: event } : event) as TEvent; +} + export function createMachine< TContext extends object, TEvent extends EventObject = EventObject, @@ -60,9 +66,7 @@ export function createMachine< typeof state === 'string' ? { value: state, context: fsmConfig.context! } : state; - const eventObject = (typeof event === 'string' - ? { type: event } - : event) as TEvent; + const eventObject = toEventObject(event); const stateConfig = fsmConfig.states[value]; if (!IS_PRODUCTION) { @@ -167,6 +171,9 @@ export function interpret< return; } state = machine.transition(state, event); + state.actions.forEach( + ({ exec }) => exec && exec(state.context, toEventObject(event)) + ); listeners.forEach(listener => listener(state)); }, subscribe: (listener: StateMachine.StateListener) => { diff --git a/packages/xstate-fsm/test/fsm.test.ts b/packages/xstate-fsm/test/fsm.test.ts index 8810932dac..ecc2c7bfc4 100644 --- a/packages/xstate-fsm/test/fsm.test.ts +++ b/packages/xstate-fsm/test/fsm.test.ts @@ -176,4 +176,35 @@ describe('interpreter', () => { toggleService.send('TOGGLE'); }); + + it('should execute actions', done => { + let executed = false; + + const actionMachine = createMachine({ + initial: 'active', + states: { + active: { + on: { + TOGGLE: { + target: 'inactive', + actions: () => { + executed = true; + } + } + } + }, + inactive: {} + } + }); + + const actionService = interpret(actionMachine).start(); + + actionService.subscribe(() => { + if (executed) { + done(); + } + }); + + actionService.send('TOGGLE'); + }); });