From 6e7f769ada754967173dc20afcd7cbde8b412691 Mon Sep 17 00:00:00 2001 From: David Khourshid Date: Mon, 2 Jan 2023 08:41:24 -0500 Subject: [PATCH] [v5] Simplify `interpreter.send(...)` method (#3568) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Simplify function signature of `interpreter.send(eventObj)` * Remove unused types * Add changeset * Cleanup types * Simplify more event-related methods and functions (#3570) * Add changeset for `@xstate/fsm` * Fix tests Co-authored-by: Mateusz Burzyński --- .changeset/eighty-coins-tease.md | 2 +- .changeset/gold-buses-thank.md | 18 ++ .changeset/shy-walls-develop.md | 2 +- .changeset/young-chefs-prove.md | 10 + README.md | 38 ++- docs/examples/counter.md | 10 +- docs/fr/examples/counter.md | 10 +- docs/fr/guides/actions.md | 4 +- docs/fr/guides/actors.md | 2 +- docs/fr/guides/communication.md | 9 +- docs/fr/guides/delays.md | 4 +- docs/fr/guides/events.md | 6 +- docs/fr/guides/interpretation.md | 13 - docs/fr/guides/statenodes.md | 2 +- docs/fr/guides/states.md | 10 +- docs/fr/guides/transitions.md | 2 +- docs/fr/packages/core/index.md | 36 ++- docs/fr/packages/xstate-fsm/index.md | 36 +-- docs/fr/packages/xstate-immer/index.md | 4 +- docs/fr/packages/xstate-svelte/index.md | 6 +- docs/fr/patterns/sequence.md | 2 +- docs/fr/recipes/ember.md | 2 +- docs/fr/recipes/react.md | 4 +- docs/fr/recipes/svelte.md | 4 +- docs/fr/tutorials/reddit.md | 2 +- docs/guides/actions.md | 4 +- docs/guides/actors.md | 2 +- docs/guides/communication.md | 9 +- docs/guides/delays.md | 4 +- docs/guides/events.md | 8 +- docs/guides/interpretation.md | 14 - docs/guides/states.md | 11 +- docs/guides/transitions.md | 2 +- docs/packages/core/index.md | 36 ++- docs/packages/xstate-fsm/index.md | 36 +-- docs/packages/xstate-immer/index.md | 4 +- docs/packages/xstate-svelte/index.md | 6 +- docs/patterns/sequence.md | 2 +- docs/recipes/ember.md | 2 +- docs/recipes/react.md | 4 +- docs/recipes/svelte.md | 4 +- docs/zh/examples/counter.md | 10 +- docs/zh/guides/actions.md | 4 +- docs/zh/guides/actors.md | 2 +- docs/zh/guides/communication.md | 9 +- docs/zh/guides/delays.md | 4 +- docs/zh/guides/events.md | 6 +- docs/zh/guides/interpretation.md | 14 - docs/zh/guides/statenodes.md | 2 +- docs/zh/guides/states.md | 11 +- docs/zh/guides/transitions.md | 2 +- docs/zh/packages/core/index.md | 33 ++- docs/zh/packages/xstate-fsm/index.md | 36 +-- docs/zh/packages/xstate-immer/index.md | 4 +- docs/zh/packages/xstate-svelte/index.md | 6 +- docs/zh/patterns/sequence.md | 2 +- docs/zh/recipes/ember.md | 2 +- docs/zh/recipes/react.md | 4 +- docs/zh/recipes/svelte.md | 4 +- examples/fetch/src/index.ts | 2 +- examples/template-js/src/main.js | 2 +- examples/template-ts/src/main.ts | 2 +- examples/todo-mvc-react/src/todos.machine.ts | 6 +- examples/todo-mvc-svelte/src/todos.machine.ts | 6 +- examples/todo-mvc-vue/src/todos.machine.ts | 6 +- packages/core/README.md | 36 ++- packages/core/src/State.ts | 3 +- packages/core/src/StateMachine.ts | 9 +- packages/core/src/StateNode.ts | 8 +- packages/core/src/actions/raise.ts | 4 +- packages/core/src/actions/send.ts | 21 +- packages/core/src/actors.ts | 3 +- packages/core/src/index.ts | 1 - packages/core/src/interpreter.ts | 14 +- packages/core/src/patterns.ts | 14 +- packages/core/src/scxml.ts | 6 +- packages/core/src/stateUtils.ts | 2 +- packages/core/src/types.ts | 45 +--- packages/core/src/utils.ts | 38 +-- packages/core/test/actionCreators.test.ts | 15 +- packages/core/test/actions.test.ts | 136 ++++++---- packages/core/test/activities.test.ts | 42 +-- packages/core/test/actor.test.ts | 56 ++-- packages/core/test/after.test.ts | 9 +- packages/core/test/assign.test.ts | 82 +++--- packages/core/test/deep.test.ts | 18 +- packages/core/test/deterministic.test.ts | 89 ++++--- packages/core/test/devTools.test.ts | 2 +- packages/core/test/event.test.ts | 22 +- packages/core/test/eventDescriptors.test.ts | 56 ++-- packages/core/test/examples/6.8.test.ts | 6 +- packages/core/test/final.test.ts | 12 +- packages/core/test/guards.test.ts | 62 +++-- packages/core/test/history.test.ts | 251 +++++++++++------- packages/core/test/id.test.ts | 2 +- .../core/test/internalTransitions.test.ts | 56 ++-- packages/core/test/interpreter.test.ts | 156 ++++++----- packages/core/test/invalid.test.ts | 23 +- packages/core/test/invoke.test.ts | 84 +++--- packages/core/test/machine.test.ts | 10 +- packages/core/test/meta.test.ts | 6 +- packages/core/test/microstep.test.ts | 18 +- packages/core/test/multiple.test.ts | 20 +- packages/core/test/parallel.test.ts | 90 +++---- packages/core/test/patterns.test.ts | 62 +++-- packages/core/test/predictableExec.test.ts | 6 +- packages/core/test/rehydration.test.ts | 2 +- packages/core/test/schema.test.ts | 4 +- packages/core/test/scxml.test.ts | 2 +- packages/core/test/state.test.ts | 114 +++++--- packages/core/test/stateIn.test.ts | 29 +- packages/core/test/tags.test.ts | 6 +- packages/core/test/transient.test.ts | 58 ++-- packages/core/test/types.test.ts | 2 +- packages/core/test/utils.ts | 2 +- packages/core/test/waitFor.test.ts | 4 +- .../xstate-analytics/test/analytics.test.ts | 4 +- packages/xstate-fsm/README.md | 10 +- packages/xstate-fsm/src/index.ts | 21 +- packages/xstate-fsm/src/types.ts | 4 +- packages/xstate-fsm/test/fsm.test.ts | 37 +-- packages/xstate-graph/src/graph.ts | 13 +- packages/xstate-immer/README.md | 4 +- packages/xstate-immer/test/immer.test.ts | 10 +- packages/xstate-inspect/examples/server.ts | 2 +- packages/xstate-inspect/src/browser.ts | 11 +- packages/xstate-inspect/src/server.ts | 9 +- packages/xstate-react/test/useActor.test.tsx | 10 +- .../xstate-react/test/useInterpret.test.tsx | 6 +- .../xstate-react/test/useMachine-fsm.test.tsx | 10 +- .../xstate-react/test/useMachine.test.tsx | 15 +- .../xstate-react/test/useSelector.test.tsx | 4 +- .../xstate-react/test/useService-fsm.test.tsx | 6 +- packages/xstate-scxml/src/scxml.ts | 8 +- .../test/fixtures/actionSend/send1.ts | 2 +- .../test/fixtures/actionSend/send2.ts | 2 +- .../test/fixtures/actionSend/send3.ts | 2 +- .../test/fixtures/actionSend/send4.ts | 2 +- .../test/fixtures/actionSend/send4b.ts | 2 +- .../test/fixtures/actionSend/send7.ts | 2 +- .../test/fixtures/actionSend/send7b.ts | 2 +- .../test/fixtures/actionSend/send8.ts | 2 +- .../test/fixtures/actionSend/send8b.ts | 2 +- .../test/fixtures/actionSend/send9.ts | 2 +- packages/xstate-scxml/test/scxml.test.ts | 2 +- packages/xstate-svelte/test/UseFsm.svelte | 2 +- packages/xstate-svelte/test/UseMachine.svelte | 2 +- .../xstate-svelte/test/UseSelector.svelte | 6 +- packages/xstate-vue/src/fsm.ts | 3 +- packages/xstate-vue/src/useActor.ts | 8 +- packages/xstate-vue/test/UseActor.vue | 2 +- .../xstate-vue/test/UseActorComponentProp.vue | 2 +- packages/xstate-vue/test/UseFSM.vue | 2 +- packages/xstate-vue/test/UseInterpret.vue | 2 +- .../test/UseMachine-no-extra-options.vue | 2 +- packages/xstate-vue/test/UseMachine.vue | 4 +- packages/xstate-vue/test/UseSelector.vue | 8 +- packages/xstate-vue/test/useActor.test.ts | 2 +- 158 files changed, 1427 insertions(+), 1207 deletions(-) create mode 100644 .changeset/gold-buses-thank.md create mode 100644 .changeset/young-chefs-prove.md diff --git a/.changeset/eighty-coins-tease.md b/.changeset/eighty-coins-tease.md index 0783dc3aa5..a73389c5b8 100644 --- a/.changeset/eighty-coins-tease.md +++ b/.changeset/eighty-coins-tease.md @@ -2,4 +2,4 @@ 'xstate': major --- -Removed third parameter (context) from Machine's transition method. If you want to transition with a particular context value you should create appropriate `State` using `State.from`. So instead of this - `machine.transition('green', 'TIMER', { elapsed: 100 })`, you should do this - `machine.transition(State.from('green', { elapsed: 100 }), 'TIMER')`. +Removed third parameter (context) from Machine's transition method. If you want to transition with a particular context value you should create appropriate `State` using `State.from`. So instead of this - `machine.transition('green', { type: 'TIMER' }, { elapsed: 100 })`, you should do this - `machine.transition(State.from('green', { elapsed: 100 }), { type: 'TIMER' })`. diff --git a/.changeset/gold-buses-thank.md b/.changeset/gold-buses-thank.md new file mode 100644 index 0000000000..672851cb4a --- /dev/null +++ b/.changeset/gold-buses-thank.md @@ -0,0 +1,18 @@ +--- +'xstate': major +--- + +The `.send(...)` method on `interpreter.send(...)` now requires the first argument (the event to send) to be an _object_; that is, either: + +- an event object (e.g. `{ type: 'someEvent' }`) +- an SCXML event object. + +The second argument (payload) is no longer supported, and should instead be included within the object: + +```diff +-actor.send('SOME_EVENT') ++actor.send({ type: 'SOME_EVENT' }) + +-actor.send('EVENT', { some: 'payload' }) ++actor.send({ type: 'EVENT', some: 'payload' }) +``` diff --git a/.changeset/shy-walls-develop.md b/.changeset/shy-walls-develop.md index 67453e4c43..3f0976d3eb 100644 --- a/.changeset/shy-walls-develop.md +++ b/.changeset/shy-walls-develop.md @@ -2,4 +2,4 @@ 'xstate': major --- -Support for compound string state values has been dropped from Machine's transition method. It's no longer allowed to call transition like this - `machine.transition('a.b', 'NEXT')`, instead it's required to use "state value" representation like this - `machine.transition({ a: 'b' }, 'NEXT')`. +Support for compound string state values has been dropped from Machine's transition method. It's no longer allowed to call transition like this - `machine.transition('a.b', { type: 'NEXT' })`, instead it's required to use "state value" representation like this - `machine.transition({ a: 'b' }, { type: 'NEXT' })`. diff --git a/.changeset/young-chefs-prove.md b/.changeset/young-chefs-prove.md new file mode 100644 index 0000000000..95b0073f4b --- /dev/null +++ b/.changeset/young-chefs-prove.md @@ -0,0 +1,10 @@ +--- +'@xstate/fsm': major +--- + +The `.send(...)` method on `interpreter.send(...)` now requires the first argument (the event to send) to be an _object_, e.g. `{ type: 'someEvent' }`. + +```diff +-actor.send('SOME_EVENT') ++actor.send({ type: 'SOME_EVENT' }) +``` diff --git a/README.md b/README.md index bcb4fcce04..0af9527eae 100644 --- a/README.md +++ b/README.md @@ -75,10 +75,10 @@ const toggleService = interpret(toggleMachine) .start(); // => 'inactive' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'active' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'inactive' ``` @@ -138,7 +138,7 @@ const dogService = interpret(fetchMachine) .onTransition((state) => console.log(state.value)) .start(); -dogService.send('FETCH'); +dogService.send({ type: 'FETCH' }); ``` @@ -213,7 +213,8 @@ const lightMachine = createMachine({ const currentState = 'green'; -const nextState = lightMachine.transition(currentState, 'TIMER').value; +const nextState = lightMachine.transition(currentState, { type: 'TIMER' }) + .value; // => 'yellow' ``` @@ -272,12 +273,13 @@ const lightMachine = createMachine({ const currentState = 'yellow'; -const nextState = lightMachine.transition(currentState, 'TIMER').value; +const nextState = lightMachine.transition(currentState, { type: 'TIMER' }) + .value; // => { // red: 'walk' // } -lightMachine.transition('red.walk', 'PED_TIMER').value; +lightMachine.transition('red.walk', { type: 'PED_TIMER' }).value; // => { // red: 'wait' // } @@ -287,15 +289,18 @@ lightMachine.transition('red.walk', 'PED_TIMER').value; ```js // ... -const waitState = lightMachine.transition({ red: 'walk' }, 'PED_TIMER').value; +const waitState = lightMachine.transition( + { red: 'walk' }, + { type: 'PED_TIMER' } +).value; // => { red: 'wait' } -lightMachine.transition(waitState, 'PED_TIMER').value; +lightMachine.transition(waitState, { type: 'PED_TIMER' }).value; // => { red: 'stop' } -lightMachine.transition({ red: 'stop' }, 'TIMER').value; +lightMachine.transition({ red: 'stop' }, { type: 'TIMER' }).value; // => 'green' ``` @@ -364,7 +369,8 @@ const wordMachine = createMachine({ } }); -const boldState = wordMachine.transition('bold.off', 'TOGGLE_BOLD').value; +const boldState = wordMachine.transition('bold.off', { type: 'TOGGLE_BOLD' }) + .value; // { // bold: 'on', @@ -380,7 +386,7 @@ const nextState = wordMachine.transition( underline: 'on', list: 'bullets' }, - 'TOGGLE_ITALICS' + { type: 'TOGGLE_ITALICS' } ).value; // { @@ -420,21 +426,25 @@ const paymentMachine = createMachine({ } }); -const checkState = paymentMachine.transition('method.cash', 'SWITCH_CHECK'); +const checkState = paymentMachine.transition('method.cash', { + type: 'SWITCH_CHECK' +}); // => State { // value: { method: 'check' }, // history: State { ... } // } -const reviewState = paymentMachine.transition(checkState, 'NEXT'); +const reviewState = paymentMachine.transition(checkState, { type: 'NEXT' }); // => State { // value: 'review', // history: State { ... } // } -const previousState = paymentMachine.transition(reviewState, 'PREVIOUS').value; +const previousState = paymentMachine.transition(reviewState, { + type: 'PREVIOUS' +}).value; // => { method: 'check' } ``` diff --git a/docs/examples/counter.md b/docs/examples/counter.md index 2dd9c53039..eb55b9695e 100644 --- a/docs/examples/counter.md +++ b/docs/examples/counter.md @@ -33,13 +33,13 @@ const counterService = interpret(counterMachine) .start(); // => 0 -counterService.send('INC'); +counterService.send({ type: 'INC' }); // => 1 -counterService.send('INC'); +counterService.send({ type: 'INC' }); // => 2 -counterService.send('DEC'); +counterService.send({ type: 'DEC' }); // => 1 ``` @@ -77,9 +77,9 @@ const counterMachine = createMachine({ // ... // assume context is { count: 9 } -counterService.send('INC'); +counterService.send({ type: 'INC' }); // => 10 -counterService.send('INC'); // no transition taken! +counterService.send({ type: 'INC' }); // no transition taken! // => 10 ``` diff --git a/docs/fr/examples/counter.md b/docs/fr/examples/counter.md index ed3ff5db2e..a4f05ae15a 100644 --- a/docs/fr/examples/counter.md +++ b/docs/fr/examples/counter.md @@ -33,13 +33,13 @@ const counterService = interpret(counterMachine) .start(); // => 0 -counterService.send('INC'); +counterService.send({ type: 'INC' }); // => 1 -counterService.send('INC'); +counterService.send({ type: 'INC' }); // => 2 -counterService.send('DEC'); +counterService.send({ type: 'DEC' }); // => 1 ``` @@ -77,9 +77,9 @@ const counterMachine = createMachine({ // ... // Supposons que le valeur du contexte était { count: 9 } -counterService.send('INC'); +counterService.send({ type: 'INC' }); // => 10 -counterService.send('INC'); // Pas de transition ! +counterService.send({ type: 'INC' }); // Pas de transition ! // => 10 ``` diff --git a/docs/fr/guides/actions.md b/docs/fr/guides/actions.md index ab1385487e..9314a8aa8b 100644 --- a/docs/fr/guides/actions.md +++ b/docs/fr/guides/actions.md @@ -355,7 +355,7 @@ const raiseActionDemo = createMachine({ RAISE: { target: 'middle', // immediately invoke the NEXT event for 'middle' - actions: raise('NEXT') + actions: raise({ type: 'NEXT' }) } } }, @@ -542,7 +542,7 @@ const loggingMachine = createMachine({ } }); -const endState = loggingMachine.transition('start', 'FINISH'); +const endState = loggingMachine.transition('start', { type: 'FINISH' }); endState.actions; // [ diff --git a/docs/fr/guides/actors.md b/docs/fr/guides/actors.md index 4b686c00a7..d769174353 100644 --- a/docs/fr/guides/actors.md +++ b/docs/fr/guides/actors.md @@ -315,7 +315,7 @@ const remoteMachine = createMachine({ online: { after: { 1000: { - actions: sendParent('REMOTE.ONLINE') + actions: sendParent({ type: 'REMOTE.ONLINE' }) } } } diff --git a/docs/fr/guides/communication.md b/docs/fr/guides/communication.md index 5b9b8c834e..28c21f42f7 100644 --- a/docs/fr/guides/communication.md +++ b/docs/fr/guides/communication.md @@ -539,9 +539,12 @@ const pongMachine = createMachine({ on: { PING: { // Sends 'PONG' event to parent machine - actions: sendParent('PONG', { - delay: 1000 - }) + actions: sendParent( + { type: 'PONG' }, + { + delay: 1000 + } + ) } } } diff --git a/docs/fr/guides/delays.md b/docs/fr/guides/delays.md index 94e0362688..6032216cf6 100644 --- a/docs/fr/guides/delays.md +++ b/docs/fr/guides/delays.md @@ -311,8 +311,8 @@ The `after: ...` property does not introduce anything new to statechart semantic states: { green: { entry: [ - send(after(1000, 'light.green'), { delay: 1000 }), - send(after(2000, 'light.green'), { delay: 2000 }) + send({ type: after(1000, 'light.green') }, { delay: 1000 }), + send({ type: after(2000, 'light.green') }, { delay: 2000 }) ], onExit: [ cancel(after(1000, 'light.green')), diff --git a/docs/fr/guides/events.md b/docs/fr/guides/events.md index 3f6657d06a..d628412700 100644 --- a/docs/fr/guides/events.md +++ b/docs/fr/guides/events.md @@ -41,11 +41,11 @@ const lightMachine = createMachine({ const { initialState } = lightMachine; -let nextState = lightMachine.transition(initialState, 'TIMER'); // string event +let nextState = lightMachine.transition(initialState, { type: 'TIMER' }); // string event console.log(nextState.value); // => 'yellow' -nextState = lightMachine.transition(nextState, { type: 'TIMER' }); // event object +nextState = lightMachine.transition(nextState, { type: { type: 'TIMER' } }); // event object console.log(nextState.value); // => 'red' ``` @@ -104,7 +104,7 @@ const skipMachine = createMachine({ }); const { initialState } = skipMachine; -const nextState = skipMachine.transition(initialState, 'CLICK'); +const nextState = skipMachine.transition(initialState, { type: 'CLICK' }); console.log(nextState.value); // => 'three' diff --git a/docs/fr/guides/interpretation.md b/docs/fr/guides/interpretation.md index da3afee8bb..778c11aaf9 100644 --- a/docs/fr/guides/interpretation.md +++ b/docs/fr/guides/interpretation.md @@ -50,23 +50,10 @@ service.start(); // As an object (preferred): service.send({ type: 'CLICK', x: 40, y: 21 }); - -// As a string: -// (same as service.send({ type: 'CLICK' })) -service.send('CLICK'); - -// As a string with an object payload: -// (same as service.send({ type: 'CLICK', x: 40, y: 21 })) -service.send('CLICK', { x: 40, y: 21 }); ``` - As an event object (e.g., `.send({ type: 'CLICK', x: 40, y: 21 })`) - The event object must have a `type: ...` string property. -- As a string (e.g., `.send('CLICK')`, which resolves to sending `{ type: 'CLICK' }`) - - The string represents the event type. -- As a string followed by an object payload (e.g., `.send('CLICK', { x: 40, y: 21 })`) - - The first string argument represents the event type. - - The second argument must be an object without a `type: ...` property. ::: warning If the service is not initialized (that is, if `service.start()` wasn't called yet), events will be **deferred** until the service is started. This means that the events won't be processed until `service.start()` is called, and then they will all be sequentially processed. diff --git a/docs/fr/guides/statenodes.md b/docs/fr/guides/statenodes.md index 7eee7a4d3d..0dcdc3ac1c 100644 --- a/docs/fr/guides/statenodes.md +++ b/docs/fr/guides/statenodes.md @@ -305,6 +305,6 @@ const machine = createMachine({ machine.initialState.hasTag('loading'); // => false -machine.transition(machine.initialState, 'FETCH').hasTag('loading'); +machine.transition(machine.initialState, { type: 'FETCH' }).hasTag('loading'); // => true ``` diff --git a/docs/fr/guides/states.md b/docs/fr/guides/states.md index f21e07f991..fa61396f8d 100644 --- a/docs/fr/guides/states.md +++ b/docs/fr/guides/states.md @@ -248,8 +248,8 @@ const machine = createMachine({ const inactiveState = machine.initialState; -inactiveState.can('TOGGLE'); // true -inactiveState.can('DO_SOMETHING'); // false +inactiveState.can({ type: 'TOGGLE' }); // true +inactiveState.can({ type: 'DO_SOMETHING' }); // false // Also takes in full event objects: inactiveState.can({ @@ -257,10 +257,10 @@ inactiveState.can({ data: 42 }); // false -const activeState = machine.transition(inactiveState, 'TOGGLE'); +const activeState = machine.transition(inactiveState, { type: 'TOGGLE' }); -activeState.can('TOGGLE'); // false -activeState.can('DO_SOMETHING'); // true, since an action will be executed +activeState.can({ type: 'TOGGLE' }); // false +activeState.can({ type: 'DO_SOMETHING' }); // true, since an action will be executed ``` A state is considered “changed” if [`state.changed`](#state-changed) is `true` and if any of the following are true: diff --git a/docs/fr/guides/transitions.md b/docs/fr/guides/transitions.md index 626877a5a4..4181a6d5b0 100644 --- a/docs/fr/guides/transitions.md +++ b/docs/fr/guides/transitions.md @@ -327,7 +327,7 @@ const gameService = interpret(gameMachine) // When 'AWARD_POINTS' is sent, a self-transition to 'PLAYING' occurs. // The transient transition to 'win' is taken because the 'didPlayerWin' // condition is satisfied. -gameService.send('AWARD_POINTS'); +gameService.send({ type: 'AWARD_POINTS' }); // => 'win' ``` diff --git a/docs/fr/packages/core/index.md b/docs/fr/packages/core/index.md index 959ded4fbd..8d0f546716 100644 --- a/docs/fr/packages/core/index.md +++ b/docs/fr/packages/core/index.md @@ -52,10 +52,10 @@ const toggleService = interpret(toggleMachine) .start(); // => 'inactive' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'active' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'inactive' ``` @@ -116,7 +116,8 @@ const lightMachine = createMachine({ const currentState = 'green'; -const nextState = lightMachine.transition(currentState, 'TIMER').value; +const nextState = lightMachine.transition(currentState, { type: 'TIMER' }) + .value; // => 'yellow' ``` @@ -170,12 +171,13 @@ const lightMachine = createMachine({ const currentState = 'yellow'; -const nextState = lightMachine.transition(currentState, 'TIMER').value; +const nextState = lightMachine.transition(currentState, { type: 'TIMER' }) + .value; // => { // red: 'walk' // } -lightMachine.transition('red.walk', 'PED_TIMER').value; +lightMachine.transition('red.walk', { type: 'PED_TIMER' }).value; // => { // red: 'wait' // } @@ -185,15 +187,18 @@ lightMachine.transition('red.walk', 'PED_TIMER').value; ```js // ... -const waitState = lightMachine.transition({ red: 'walk' }, 'PED_TIMER').value; +const waitState = lightMachine.transition( + { red: 'walk' }, + { type: 'PED_TIMER' } +).value; // => { red: 'wait' } -lightMachine.transition(waitState, 'PED_TIMER').value; +lightMachine.transition(waitState, { type: 'PED_TIMER' }).value; // => { red: 'stop' } -lightMachine.transition({ red: 'stop' }, 'TIMER').value; +lightMachine.transition({ red: 'stop' }, { type: 'TIMER' }).value; // => 'green' ``` @@ -257,7 +262,8 @@ const wordMachine = createMachine({ } }); -const boldState = wordMachine.transition('bold.off', 'TOGGLE_BOLD').value; +const boldState = wordMachine.transition('bold.off', { type: 'TOGGLE_BOLD' }) + .value; // { // bold: 'on', @@ -273,7 +279,7 @@ const nextState = wordMachine.transition( underline: 'on', list: 'bullets' }, - 'TOGGLE_ITALICS' + { type: 'TOGGLE_ITALICS' } ).value; // { @@ -308,21 +314,25 @@ const paymentMachine = createMachine({ } }); -const checkState = paymentMachine.transition('method.cash', 'SWITCH_CHECK'); +const checkState = paymentMachine.transition('method.cash', { + type: 'SWITCH_CHECK' +}); // => State { // value: { method: 'check' }, // history: State { ... } // } -const reviewState = paymentMachine.transition(checkState, 'NEXT'); +const reviewState = paymentMachine.transition(checkState, { type: 'NEXT' }); // => State { // value: 'review', // history: State { ... } // } -const previousState = paymentMachine.transition(reviewState, 'PREVIOUS').value; +const previousState = paymentMachine.transition(reviewState, { + type: 'PREVIOUS' +}).value; // => { method: 'check' } ``` diff --git a/docs/fr/packages/xstate-fsm/index.md b/docs/fr/packages/xstate-fsm/index.md index f189e4c150..2b9e3b3a93 100644 --- a/docs/fr/packages/xstate-fsm/index.md +++ b/docs/fr/packages/xstate-fsm/index.md @@ -72,9 +72,11 @@ const toggleMachine = createMachine({ const { initialState } = toggleMachine; -const toggledState = toggleMachine.transition(initialState, 'TOGGLE'); +const toggledState = toggleMachine.transition(initialState, { type: 'TOGGLE' }); toggledState.value; -const untoggledState = toggleMachine.transition(toggledState, 'TOGGLE'); +const untoggledState = toggleMachine.transition(toggledState, { + type: 'TOGGLE' +}); untoggledState.value; // => 'inactive' ``` @@ -92,8 +94,8 @@ toggleService.subscribe((state) => { console.log(state.value); }); -toggleService.send('TOGGLE'); -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); +toggleService.send({ type: 'TOGGLE' }); toggleService.stop(); ``` @@ -192,7 +194,7 @@ String syntax: Using the string or object syntax is useful for handling actions in a custom way, rather than baking in the implementation details to your machine: ```js -const nextState = machine.transition(); +const nextState = machine.transition(state, event); nextState.actions.forEach((action) => { if (action.type === 'focus') { @@ -212,10 +214,10 @@ A pure transition function that returns the next state given the current `state` The state can be a `string` state name, or a `State` object (the return type of `machine.transition(...)`). -| Argument | Type | Description | -| -------- | ----------------------------------- | ---------------------------------------------------------------- | -| `state` | `string` or `State` object | The current state to transition from | -| `event` | `string` or `{ type: string, ... }` | The event that transitions the current `state` to the next state | +| Argument | Type | Description | +| -------- | -------------------------- | ---------------------------------------------------------------- | +| `state` | `string` or `State` object | The current state to transition from | +| `event` | `{ type: string, ... }` | The event that transitions the current `state` to the next state | **Returns:** @@ -224,8 +226,8 @@ A `State` object, which represents the next state. **Example:** ```js -const yellowState = machine.transition('green', 'TIMER'); -const redState = machine.transition(yellowState, 'TIMER'); +const yellowState = machine.transition('green', { type: 'TIMER' }); +const redState = machine.transition(yellowState, { type: 'TIMER' }); const greenState = machine.transition(yellowState, { type: 'TIMER' }); // => { value: 'green', ... } ``` @@ -265,7 +267,7 @@ const subscription = service.subscribe((state) => { service.start(); -service.send('SOME_EVENT'); +service.send({ type: 'SOME_EVENT' }); service.send({ type: 'ANOTHER_EVENT' }); subscription.unsubscribe(); @@ -289,9 +291,9 @@ A subscription object with an `unsubscribe` method. Sends an `event` to the interpreted machine. The event can be a string (e.g., `"EVENT"`) or an object with a `type` property (e.g., `{ type: "EVENT" }`). -| Argument | Type | Description | -| -------- | ----------------------------------- | ------------------------------------------------ | -| `event` | `string` or `{ type: string, ... }` | The event to be sent to the interpreted machine. | +| Argument | Type | Description | +| -------- | ----------------------- | ------------------------------------------------ | +| `event` | `{ type: string, ... }` | The event to be sent to the interpreted machine. | ### `service.start()` @@ -413,8 +415,8 @@ lightService.subscribe((state) => { }); lightService.start(); -lightService.send('TIMER'); -lightService.send('TIMER'); +lightService.send({ type: 'TIMER' }); +lightService.send({ type: 'TIMER' }); // => logs { // value: 'red', // context: { redLights: 1 }, diff --git a/docs/fr/packages/xstate-immer/index.md b/docs/fr/packages/xstate-immer/index.md index 8cf4c3a17b..a630b0b67c 100644 --- a/docs/fr/packages/xstate-immer/index.md +++ b/docs/fr/packages/xstate-immer/index.md @@ -87,13 +87,13 @@ const toggleService = interpret(toggleMachine) }) .start(); -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // { count: 1, level: 0 } toggleService.send(levelUpdater.update(9)); // { count: 1, level: 9 } -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // { count: 2, level: 9 } toggleService.send(levelUpdater.update(-100)); diff --git a/docs/fr/packages/xstate-svelte/index.md b/docs/fr/packages/xstate-svelte/index.md index 85b1d10b58..6858f56df9 100644 --- a/docs/fr/packages/xstate-svelte/index.md +++ b/docs/fr/packages/xstate-svelte/index.md @@ -205,10 +205,10 @@ A function that returns [Svelte store](https://svelte.dev/docs#svelte_store) rep $: $service.context.count && withoutSelector++; - - @@ -362,7 +362,7 @@ export const toggleService = interpret(toggleMachine).start(); import { toggleService } from './service'; - ); diff --git a/docs/fr/recipes/svelte.md b/docs/fr/recipes/svelte.md index c4cf48d6a9..50babebd80 100644 --- a/docs/fr/recipes/svelte.md +++ b/docs/fr/recipes/svelte.md @@ -57,7 +57,7 @@ export const toggleMachine = createMachine({ }).start() - ``` @@ -74,7 +74,7 @@ The toggleService has a `.subscribe` function that is similar to Svelte stores, const toggleService = interpret(toggleMachine).start(); - ``` diff --git a/docs/fr/tutorials/reddit.md b/docs/fr/tutorials/reddit.md index 269948ff7b..4f3208aaaa 100644 --- a/docs/fr/tutorials/reddit.md +++ b/docs/fr/tutorials/reddit.md @@ -223,7 +223,7 @@ describe('reddit machine (live)', () => { // Test that when the 'SELECT' event is sent, the machine eventually // reaches the { selected: 'loaded' } state with posts - redditService.send('SELECT', { name: 'reactjs' }); + redditService.send({ type: 'SELECT', name: 'reactjs' }); }); }); ``` diff --git a/docs/guides/actions.md b/docs/guides/actions.md index f365533680..d1390a27a3 100644 --- a/docs/guides/actions.md +++ b/docs/guides/actions.md @@ -376,7 +376,7 @@ const raiseActionDemo = createMachine({ RAISE: { target: 'middle', // immediately invoke the NEXT event for 'middle' - actions: raise('NEXT') + actions: raise({ type: 'NEXT' }) } } }, @@ -563,7 +563,7 @@ const loggingMachine = createMachine({ } }); -const endState = loggingMachine.transition('start', 'FINISH'); +const endState = loggingMachine.transition('start', { type: 'FINISH' }); endState.actions; // [ diff --git a/docs/guides/actors.md b/docs/guides/actors.md index 4b686c00a7..d769174353 100644 --- a/docs/guides/actors.md +++ b/docs/guides/actors.md @@ -315,7 +315,7 @@ const remoteMachine = createMachine({ online: { after: { 1000: { - actions: sendParent('REMOTE.ONLINE') + actions: sendParent({ type: 'REMOTE.ONLINE' }) } } } diff --git a/docs/guides/communication.md b/docs/guides/communication.md index 5b9b8c834e..28c21f42f7 100644 --- a/docs/guides/communication.md +++ b/docs/guides/communication.md @@ -539,9 +539,12 @@ const pongMachine = createMachine({ on: { PING: { // Sends 'PONG' event to parent machine - actions: sendParent('PONG', { - delay: 1000 - }) + actions: sendParent( + { type: 'PONG' }, + { + delay: 1000 + } + ) } } } diff --git a/docs/guides/delays.md b/docs/guides/delays.md index 91f97f5a3d..e73a7b8e7b 100644 --- a/docs/guides/delays.md +++ b/docs/guides/delays.md @@ -312,8 +312,8 @@ The `after: ...` property does not introduce anything new to statechart semantic states: { green: { entry: [ - send(after(1000, 'light.green'), { delay: 1000 }), - send(after(2000, 'light.green'), { delay: 2000 }) + send({ type: after(1000, 'light.green') }, { delay: 1000 }), + send({ type: after(2000, 'light.green') }, { delay: 2000 }) ], onExit: [ cancel(after(1000, 'light.green')), diff --git a/docs/guides/events.md b/docs/guides/events.md index 3f6657d06a..b44418ac7d 100644 --- a/docs/guides/events.md +++ b/docs/guides/events.md @@ -41,11 +41,7 @@ const lightMachine = createMachine({ const { initialState } = lightMachine; -let nextState = lightMachine.transition(initialState, 'TIMER'); // string event -console.log(nextState.value); -// => 'yellow' - -nextState = lightMachine.transition(nextState, { type: 'TIMER' }); // event object +nextState = lightMachine.transition(nextState, { type: 'TIMER' }); console.log(nextState.value); // => 'red' ``` @@ -104,7 +100,7 @@ const skipMachine = createMachine({ }); const { initialState } = skipMachine; -const nextState = skipMachine.transition(initialState, 'CLICK'); +const nextState = skipMachine.transition(initialState, { type: 'CLICK' }); console.log(nextState.value); // => 'three' diff --git a/docs/guides/interpretation.md b/docs/guides/interpretation.md index 73e0f723ba..6cb06fea17 100644 --- a/docs/guides/interpretation.md +++ b/docs/guides/interpretation.md @@ -48,25 +48,11 @@ Events are sent to a running service by calling `service.send(event)`. There are ```js {5,8,12} service.start(); -// As an object (preferred): service.send({ type: 'CLICK', x: 40, y: 21 }); - -// As a string: -// (same as service.send({ type: 'CLICK' })) -service.send('CLICK'); - -// As a string with an object payload: -// (same as service.send({ type: 'CLICK', x: 40, y: 21 })) -service.send('CLICK', { x: 40, y: 21 }); ``` - As an event object (e.g., `.send({ type: 'CLICK', x: 40, y: 21 })`) - The event object must have a `type: ...` string property. -- As a string (e.g., `.send('CLICK')`, which resolves to sending `{ type: 'CLICK' }`) - - The string represents the event type. -- As a string followed by an object payload (e.g., `.send('CLICK', { x: 40, y: 21 })`) - - The first string argument represents the event type. - - The second argument must be an object without a `type: ...` property. ::: warning If the service is not initialized (that is, if `service.start()` wasn't called yet), events will be **deferred** until the service is started. This means that the events won't be processed until `service.start()` is called, and then they will all be sequentially processed. diff --git a/docs/guides/states.md b/docs/guides/states.md index f21e07f991..686bae9295 100644 --- a/docs/guides/states.md +++ b/docs/guides/states.md @@ -248,19 +248,18 @@ const machine = createMachine({ const inactiveState = machine.initialState; -inactiveState.can('TOGGLE'); // true -inactiveState.can('DO_SOMETHING'); // false +inactiveState.can({ type: 'TOGGLE' }); // true +inactiveState.can({ type: 'DO_SOMETHING' }); // false -// Also takes in full event objects: inactiveState.can({ type: 'DO_SOMETHING', data: 42 }); // false -const activeState = machine.transition(inactiveState, 'TOGGLE'); +const activeState = machine.transition(inactiveState, { type: 'TOGGLE' }); -activeState.can('TOGGLE'); // false -activeState.can('DO_SOMETHING'); // true, since an action will be executed +activeState.can({ type: 'TOGGLE' }); // false +activeState.can({ type: 'DO_SOMETHING' }); // true, since an action will be executed ``` A state is considered “changed” if [`state.changed`](#state-changed) is `true` and if any of the following are true: diff --git a/docs/guides/transitions.md b/docs/guides/transitions.md index 459df916ca..404f0f49ee 100644 --- a/docs/guides/transitions.md +++ b/docs/guides/transitions.md @@ -327,7 +327,7 @@ const gameService = interpret(gameMachine) // When 'AWARD_POINTS' is sent, a self-transition to 'PLAYING' occurs. // The transient transition to 'win' is taken because the 'didPlayerWin' // condition is satisfied. -gameService.send('AWARD_POINTS'); +gameService.send({ type: 'AWARD_POINTS' }); // => 'win' ``` diff --git a/docs/packages/core/index.md b/docs/packages/core/index.md index 959ded4fbd..8d0f546716 100644 --- a/docs/packages/core/index.md +++ b/docs/packages/core/index.md @@ -52,10 +52,10 @@ const toggleService = interpret(toggleMachine) .start(); // => 'inactive' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'active' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'inactive' ``` @@ -116,7 +116,8 @@ const lightMachine = createMachine({ const currentState = 'green'; -const nextState = lightMachine.transition(currentState, 'TIMER').value; +const nextState = lightMachine.transition(currentState, { type: 'TIMER' }) + .value; // => 'yellow' ``` @@ -170,12 +171,13 @@ const lightMachine = createMachine({ const currentState = 'yellow'; -const nextState = lightMachine.transition(currentState, 'TIMER').value; +const nextState = lightMachine.transition(currentState, { type: 'TIMER' }) + .value; // => { // red: 'walk' // } -lightMachine.transition('red.walk', 'PED_TIMER').value; +lightMachine.transition('red.walk', { type: 'PED_TIMER' }).value; // => { // red: 'wait' // } @@ -185,15 +187,18 @@ lightMachine.transition('red.walk', 'PED_TIMER').value; ```js // ... -const waitState = lightMachine.transition({ red: 'walk' }, 'PED_TIMER').value; +const waitState = lightMachine.transition( + { red: 'walk' }, + { type: 'PED_TIMER' } +).value; // => { red: 'wait' } -lightMachine.transition(waitState, 'PED_TIMER').value; +lightMachine.transition(waitState, { type: 'PED_TIMER' }).value; // => { red: 'stop' } -lightMachine.transition({ red: 'stop' }, 'TIMER').value; +lightMachine.transition({ red: 'stop' }, { type: 'TIMER' }).value; // => 'green' ``` @@ -257,7 +262,8 @@ const wordMachine = createMachine({ } }); -const boldState = wordMachine.transition('bold.off', 'TOGGLE_BOLD').value; +const boldState = wordMachine.transition('bold.off', { type: 'TOGGLE_BOLD' }) + .value; // { // bold: 'on', @@ -273,7 +279,7 @@ const nextState = wordMachine.transition( underline: 'on', list: 'bullets' }, - 'TOGGLE_ITALICS' + { type: 'TOGGLE_ITALICS' } ).value; // { @@ -308,21 +314,25 @@ const paymentMachine = createMachine({ } }); -const checkState = paymentMachine.transition('method.cash', 'SWITCH_CHECK'); +const checkState = paymentMachine.transition('method.cash', { + type: 'SWITCH_CHECK' +}); // => State { // value: { method: 'check' }, // history: State { ... } // } -const reviewState = paymentMachine.transition(checkState, 'NEXT'); +const reviewState = paymentMachine.transition(checkState, { type: 'NEXT' }); // => State { // value: 'review', // history: State { ... } // } -const previousState = paymentMachine.transition(reviewState, 'PREVIOUS').value; +const previousState = paymentMachine.transition(reviewState, { + type: 'PREVIOUS' +}).value; // => { method: 'check' } ``` diff --git a/docs/packages/xstate-fsm/index.md b/docs/packages/xstate-fsm/index.md index f189e4c150..2b9e3b3a93 100644 --- a/docs/packages/xstate-fsm/index.md +++ b/docs/packages/xstate-fsm/index.md @@ -72,9 +72,11 @@ const toggleMachine = createMachine({ const { initialState } = toggleMachine; -const toggledState = toggleMachine.transition(initialState, 'TOGGLE'); +const toggledState = toggleMachine.transition(initialState, { type: 'TOGGLE' }); toggledState.value; -const untoggledState = toggleMachine.transition(toggledState, 'TOGGLE'); +const untoggledState = toggleMachine.transition(toggledState, { + type: 'TOGGLE' +}); untoggledState.value; // => 'inactive' ``` @@ -92,8 +94,8 @@ toggleService.subscribe((state) => { console.log(state.value); }); -toggleService.send('TOGGLE'); -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); +toggleService.send({ type: 'TOGGLE' }); toggleService.stop(); ``` @@ -192,7 +194,7 @@ String syntax: Using the string or object syntax is useful for handling actions in a custom way, rather than baking in the implementation details to your machine: ```js -const nextState = machine.transition(); +const nextState = machine.transition(state, event); nextState.actions.forEach((action) => { if (action.type === 'focus') { @@ -212,10 +214,10 @@ A pure transition function that returns the next state given the current `state` The state can be a `string` state name, or a `State` object (the return type of `machine.transition(...)`). -| Argument | Type | Description | -| -------- | ----------------------------------- | ---------------------------------------------------------------- | -| `state` | `string` or `State` object | The current state to transition from | -| `event` | `string` or `{ type: string, ... }` | The event that transitions the current `state` to the next state | +| Argument | Type | Description | +| -------- | -------------------------- | ---------------------------------------------------------------- | +| `state` | `string` or `State` object | The current state to transition from | +| `event` | `{ type: string, ... }` | The event that transitions the current `state` to the next state | **Returns:** @@ -224,8 +226,8 @@ A `State` object, which represents the next state. **Example:** ```js -const yellowState = machine.transition('green', 'TIMER'); -const redState = machine.transition(yellowState, 'TIMER'); +const yellowState = machine.transition('green', { type: 'TIMER' }); +const redState = machine.transition(yellowState, { type: 'TIMER' }); const greenState = machine.transition(yellowState, { type: 'TIMER' }); // => { value: 'green', ... } ``` @@ -265,7 +267,7 @@ const subscription = service.subscribe((state) => { service.start(); -service.send('SOME_EVENT'); +service.send({ type: 'SOME_EVENT' }); service.send({ type: 'ANOTHER_EVENT' }); subscription.unsubscribe(); @@ -289,9 +291,9 @@ A subscription object with an `unsubscribe` method. Sends an `event` to the interpreted machine. The event can be a string (e.g., `"EVENT"`) or an object with a `type` property (e.g., `{ type: "EVENT" }`). -| Argument | Type | Description | -| -------- | ----------------------------------- | ------------------------------------------------ | -| `event` | `string` or `{ type: string, ... }` | The event to be sent to the interpreted machine. | +| Argument | Type | Description | +| -------- | ----------------------- | ------------------------------------------------ | +| `event` | `{ type: string, ... }` | The event to be sent to the interpreted machine. | ### `service.start()` @@ -413,8 +415,8 @@ lightService.subscribe((state) => { }); lightService.start(); -lightService.send('TIMER'); -lightService.send('TIMER'); +lightService.send({ type: 'TIMER' }); +lightService.send({ type: 'TIMER' }); // => logs { // value: 'red', // context: { redLights: 1 }, diff --git a/docs/packages/xstate-immer/index.md b/docs/packages/xstate-immer/index.md index bf1dd85380..b2b36e75d3 100644 --- a/docs/packages/xstate-immer/index.md +++ b/docs/packages/xstate-immer/index.md @@ -87,13 +87,13 @@ const toggleService = interpret(toggleMachine) }) .start(); -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // { count: 1, level: 0 } toggleService.send(levelUpdater.update(9)); // { count: 1, level: 9 } -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // { count: 2, level: 9 } toggleService.send(levelUpdater.update(-100)); diff --git a/docs/packages/xstate-svelte/index.md b/docs/packages/xstate-svelte/index.md index 85b1d10b58..6858f56df9 100644 --- a/docs/packages/xstate-svelte/index.md +++ b/docs/packages/xstate-svelte/index.md @@ -205,10 +205,10 @@ A function that returns [Svelte store](https://svelte.dev/docs#svelte_store) rep $: $service.context.count && withoutSelector++; - - @@ -362,7 +362,7 @@ export const toggleService = interpret(toggleMachine).start(); import { toggleService } from './service'; - ); diff --git a/docs/recipes/svelte.md b/docs/recipes/svelte.md index c4cf48d6a9..1b902682a2 100644 --- a/docs/recipes/svelte.md +++ b/docs/recipes/svelte.md @@ -57,7 +57,7 @@ export const toggleMachine = createMachine({ }).start() - ``` @@ -74,7 +74,7 @@ The toggleService has a `.subscribe` function that is similar to Svelte stores, const toggleService = interpret(toggleMachine).start(); - ``` diff --git a/docs/zh/examples/counter.md b/docs/zh/examples/counter.md index c9b4fbacc9..060a0278ef 100644 --- a/docs/zh/examples/counter.md +++ b/docs/zh/examples/counter.md @@ -33,13 +33,13 @@ const counterService = interpret(counterMachine) .start(); // => 0 -counterService.send('INC'); +counterService.send({ type: 'INC' }); // => 1 -counterService.send('INC'); +counterService.send({ type: 'INC' }); // => 2 -counterService.send('DEC'); +counterService.send({ type: 'DEC' }); // => 1 ``` @@ -77,9 +77,9 @@ const counterMachine = createMachine({ // ... // assume context is { count: 9 } -counterService.send('INC'); +counterService.send({ type: 'INC' }); // => 10 -counterService.send('INC'); // no transition taken! +counterService.send({ type: 'INC' }); // no transition taken! // => 10 ``` diff --git a/docs/zh/guides/actions.md b/docs/zh/guides/actions.md index 041ba53f12..943aeb3149 100644 --- a/docs/zh/guides/actions.md +++ b/docs/zh/guides/actions.md @@ -354,7 +354,7 @@ const raiseActionDemo = createMachine({ RAISE: { target: 'middle', // 立即为“middle”调用 NEXT 事件 - actions: raise('NEXT') + actions: raise({ type: 'NEXT' }) } } }, @@ -541,7 +541,7 @@ const loggingMachine = createMachine({ } }); -const endState = loggingMachine.transition('start', 'FINISH'); +const endState = loggingMachine.transition('start', { type: 'FINISH' }); endState.actions; // [ diff --git a/docs/zh/guides/actors.md b/docs/zh/guides/actors.md index 513925f1f5..0ff1a90295 100644 --- a/docs/zh/guides/actors.md +++ b/docs/zh/guides/actors.md @@ -315,7 +315,7 @@ const remoteMachine = createMachine({ online: { after: { 1000: { - actions: sendParent('REMOTE.ONLINE') + actions: sendParent({ type: 'REMOTE.ONLINE' }) } } } diff --git a/docs/zh/guides/communication.md b/docs/zh/guides/communication.md index 51062b90bc..87be1a4458 100644 --- a/docs/zh/guides/communication.md +++ b/docs/zh/guides/communication.md @@ -536,9 +536,12 @@ const pongMachine = createMachine({ on: { PING: { // 向父状态机发送“PONG”事件 - actions: sendParent('PONG', { - delay: 1000 - }) + actions: sendParent( + { type: 'PONG' }, + { + delay: 1000 + } + ) } } } diff --git a/docs/zh/guides/delays.md b/docs/zh/guides/delays.md index cf1e1e8768..5aeec58cab 100644 --- a/docs/zh/guides/delays.md +++ b/docs/zh/guides/delays.md @@ -311,8 +311,8 @@ service.clock.increment(1000); states: { green: { entry: [ - send(after(1000, 'light.green'), { delay: 1000 }), - send(after(2000, 'light.green'), { delay: 2000 }) + send({ type: after(1000, 'light.green') }, { delay: 1000 }), + send({ type: after(2000, 'light.green') }, { delay: 2000 }) ], onExit: [ cancel(after(1000, 'light.green')), diff --git a/docs/zh/guides/events.md b/docs/zh/guides/events.md index cc6717203e..0b7c94cdbd 100644 --- a/docs/zh/guides/events.md +++ b/docs/zh/guides/events.md @@ -41,10 +41,6 @@ const lightMachine = createMachine({ const { initialState } = lightMachine; -let nextState = lightMachine.transition(initialState, 'TIMER'); // 字符串事件 -console.log(nextState.value); -// => 'yellow' - nextState = lightMachine.transition(nextState, { type: 'TIMER' }); // 事件对象 console.log(nextState.value); // => 'red' @@ -103,7 +99,7 @@ const skipMachine = createMachine({ }); const { initialState } = skipMachine; -const nextState = skipMachine.transition(initialState, 'CLICK'); +const nextState = skipMachine.transition(initialState, { type: 'CLICK' }); console.log(nextState.value); // => 'three' diff --git a/docs/zh/guides/interpretation.md b/docs/zh/guides/interpretation.md index 37982ca6e0..c1b07dfcd7 100644 --- a/docs/zh/guides/interpretation.md +++ b/docs/zh/guides/interpretation.md @@ -48,25 +48,11 @@ service.stop(); ```js {5,8,12} service.start(); -// 作为对象(首选): service.send({ type: 'CLICK', x: 40, y: 21 }); - -// 作为字符串: -// (与 service.send({ type: 'CLICK' }) 一样) -service.send('CLICK'); - -// 作为带有对象负载的字符串: -// (同 service.send({ type: 'CLICK', x: 40, y: 21 })) -service.send('CLICK', { x: 40, y: 21 }); ``` - 作为事件对象(例如,`.send({ type: 'CLICK', x: 40, y: 21 })`) - 事件对象必须有一个 `type: ...` 字符串属性。 -- 作为字符串(例如,`.send('CLICK')`,它解析为发送 `{ type: 'CLICK' }`) - - 该字符串表示事件类型。 -- 作为后跟对象有效负载的字符串(例如,`.send('CLICK', { x: 40, y: 21 })`) - - 第一个字符串参数表示事件类型。 - - 第二个参数必须是一个没有 `type: ...` 属性的对象。 ::: warning 如果服务未初始化(即,如果尚未调用`service.start()`),则事件将**延迟**,直到服务启动。 这意味着在调用 `service.start()` 之前不会处理事件,然后它们将被顺序处理。 diff --git a/docs/zh/guides/statenodes.md b/docs/zh/guides/statenodes.md index 7d3af2ab78..58086d3ff1 100644 --- a/docs/zh/guides/statenodes.md +++ b/docs/zh/guides/statenodes.md @@ -305,6 +305,6 @@ const machine = createMachine({ machine.initialState.hasTag('loading'); // => false -machine.transition(machine.initialState, 'FETCH').hasTag('loading'); +machine.transition(machine.initialState, { type: 'FETCH' }).hasTag('loading'); // => true ``` diff --git a/docs/zh/guides/states.md b/docs/zh/guides/states.md index dbe68071c6..6e08266b65 100644 --- a/docs/zh/guides/states.md +++ b/docs/zh/guides/states.md @@ -248,19 +248,18 @@ const machine = createMachine({ const inactiveState = machine.initialState; -inactiveState.can('TOGGLE'); // true -inactiveState.can('DO_SOMETHING'); // false +inactiveState.can({ type: 'TOGGLE' }); // true +inactiveState.can({ type: 'DO_SOMETHING' }); // false -// 还接收完整的 event 对象: inactiveState.can({ type: 'DO_SOMETHING', data: 42 }); // false -const activeState = machine.transition(inactiveState, 'TOGGLE'); +const activeState = machine.transition(inactiveState, { type: 'TOGGLE' }); -activeState.can('TOGGLE'); // false -activeState.can('DO_SOMETHING'); // true, 因为一个 action 将被执行 +activeState.can({ type: 'TOGGLE' }); // false +activeState.can({ type: 'DO_SOMETHING' }); // true, 因为一个 action 将被执行 ``` 如果 [`state.changed`](#state-changed) 为 `true`,并且以下任何一项为 `true`,则状态被视为“changed”: diff --git a/docs/zh/guides/transitions.md b/docs/zh/guides/transitions.md index 3d32fce6e7..b9763d6051 100644 --- a/docs/zh/guides/transitions.md +++ b/docs/zh/guides/transitions.md @@ -319,7 +319,7 @@ const gameService = interpret(gameMachine) // 当发送“AWARD_POINTS”时,会发生自我转换到“PLAYING”。 // 由于满足“didPlayerWin”条件,因此会进行到“win”的瞬间转换。 -gameService.send('AWARD_POINTS'); +gameService.send({ type: 'AWARD_POINTS' }); // => 'win' ``` diff --git a/docs/zh/packages/core/index.md b/docs/zh/packages/core/index.md index 959ded4fbd..51191459f9 100644 --- a/docs/zh/packages/core/index.md +++ b/docs/zh/packages/core/index.md @@ -52,10 +52,10 @@ const toggleService = interpret(toggleMachine) .start(); // => 'inactive' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'active' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'inactive' ``` @@ -116,7 +116,8 @@ const lightMachine = createMachine({ const currentState = 'green'; -const nextState = lightMachine.transition(currentState, 'TIMER').value; +const nextState = lightMachine.transition(currentState, { type: 'TIMER' }) + .value; // => 'yellow' ``` @@ -175,7 +176,7 @@ const nextState = lightMachine.transition(currentState, 'TIMER').value; // red: 'walk' // } -lightMachine.transition('red.walk', 'PED_TIMER').value; +lightMachine.transition('red.walk', { type: 'PED_TIMER' }).value; // => { // red: 'wait' // } @@ -185,15 +186,18 @@ lightMachine.transition('red.walk', 'PED_TIMER').value; ```js // ... -const waitState = lightMachine.transition({ red: 'walk' }, 'PED_TIMER').value; +const waitState = lightMachine.transition( + { red: 'walk' }, + { type: 'PED_TIMER' } +).value; // => { red: 'wait' } -lightMachine.transition(waitState, 'PED_TIMER').value; +lightMachine.transition(waitState, { type: 'PED_TIMER' }).value; // => { red: 'stop' } -lightMachine.transition({ red: 'stop' }, 'TIMER').value; +lightMachine.transition({ red: 'stop' }, { type: 'TIMER' }).value; // => 'green' ``` @@ -257,7 +261,8 @@ const wordMachine = createMachine({ } }); -const boldState = wordMachine.transition('bold.off', 'TOGGLE_BOLD').value; +const boldState = wordMachine.transition('bold.off', { type: 'TOGGLE_BOLD' }) + .value; // { // bold: 'on', @@ -273,7 +278,7 @@ const nextState = wordMachine.transition( underline: 'on', list: 'bullets' }, - 'TOGGLE_ITALICS' + { type: 'TOGGLE_ITALICS' } ).value; // { @@ -308,21 +313,25 @@ const paymentMachine = createMachine({ } }); -const checkState = paymentMachine.transition('method.cash', 'SWITCH_CHECK'); +const checkState = paymentMachine.transition('method.cash', { + type: 'SWITCH_CHECK' +}); // => State { // value: { method: 'check' }, // history: State { ... } // } -const reviewState = paymentMachine.transition(checkState, 'NEXT'); +const reviewState = paymentMachine.transition(checkState, { type: 'NEXT' }); // => State { // value: 'review', // history: State { ... } // } -const previousState = paymentMachine.transition(reviewState, 'PREVIOUS').value; +const previousState = paymentMachine.transition(reviewState, { + type: 'PREVIOUS' +}).value; // => { method: 'check' } ``` diff --git a/docs/zh/packages/xstate-fsm/index.md b/docs/zh/packages/xstate-fsm/index.md index f189e4c150..2b9e3b3a93 100644 --- a/docs/zh/packages/xstate-fsm/index.md +++ b/docs/zh/packages/xstate-fsm/index.md @@ -72,9 +72,11 @@ const toggleMachine = createMachine({ const { initialState } = toggleMachine; -const toggledState = toggleMachine.transition(initialState, 'TOGGLE'); +const toggledState = toggleMachine.transition(initialState, { type: 'TOGGLE' }); toggledState.value; -const untoggledState = toggleMachine.transition(toggledState, 'TOGGLE'); +const untoggledState = toggleMachine.transition(toggledState, { + type: 'TOGGLE' +}); untoggledState.value; // => 'inactive' ``` @@ -92,8 +94,8 @@ toggleService.subscribe((state) => { console.log(state.value); }); -toggleService.send('TOGGLE'); -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); +toggleService.send({ type: 'TOGGLE' }); toggleService.stop(); ``` @@ -192,7 +194,7 @@ String syntax: Using the string or object syntax is useful for handling actions in a custom way, rather than baking in the implementation details to your machine: ```js -const nextState = machine.transition(); +const nextState = machine.transition(state, event); nextState.actions.forEach((action) => { if (action.type === 'focus') { @@ -212,10 +214,10 @@ A pure transition function that returns the next state given the current `state` The state can be a `string` state name, or a `State` object (the return type of `machine.transition(...)`). -| Argument | Type | Description | -| -------- | ----------------------------------- | ---------------------------------------------------------------- | -| `state` | `string` or `State` object | The current state to transition from | -| `event` | `string` or `{ type: string, ... }` | The event that transitions the current `state` to the next state | +| Argument | Type | Description | +| -------- | -------------------------- | ---------------------------------------------------------------- | +| `state` | `string` or `State` object | The current state to transition from | +| `event` | `{ type: string, ... }` | The event that transitions the current `state` to the next state | **Returns:** @@ -224,8 +226,8 @@ A `State` object, which represents the next state. **Example:** ```js -const yellowState = machine.transition('green', 'TIMER'); -const redState = machine.transition(yellowState, 'TIMER'); +const yellowState = machine.transition('green', { type: 'TIMER' }); +const redState = machine.transition(yellowState, { type: 'TIMER' }); const greenState = machine.transition(yellowState, { type: 'TIMER' }); // => { value: 'green', ... } ``` @@ -265,7 +267,7 @@ const subscription = service.subscribe((state) => { service.start(); -service.send('SOME_EVENT'); +service.send({ type: 'SOME_EVENT' }); service.send({ type: 'ANOTHER_EVENT' }); subscription.unsubscribe(); @@ -289,9 +291,9 @@ A subscription object with an `unsubscribe` method. Sends an `event` to the interpreted machine. The event can be a string (e.g., `"EVENT"`) or an object with a `type` property (e.g., `{ type: "EVENT" }`). -| Argument | Type | Description | -| -------- | ----------------------------------- | ------------------------------------------------ | -| `event` | `string` or `{ type: string, ... }` | The event to be sent to the interpreted machine. | +| Argument | Type | Description | +| -------- | ----------------------- | ------------------------------------------------ | +| `event` | `{ type: string, ... }` | The event to be sent to the interpreted machine. | ### `service.start()` @@ -413,8 +415,8 @@ lightService.subscribe((state) => { }); lightService.start(); -lightService.send('TIMER'); -lightService.send('TIMER'); +lightService.send({ type: 'TIMER' }); +lightService.send({ type: 'TIMER' }); // => logs { // value: 'red', // context: { redLights: 1 }, diff --git a/docs/zh/packages/xstate-immer/index.md b/docs/zh/packages/xstate-immer/index.md index 06c50bfcd7..79ad14ddfc 100644 --- a/docs/zh/packages/xstate-immer/index.md +++ b/docs/zh/packages/xstate-immer/index.md @@ -87,13 +87,13 @@ const toggleService = interpret(toggleMachine) }) .start(); -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // { count: 1, level: 0 } toggleService.send(levelUpdater.update(9)); // { count: 1, level: 9 } -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // { count: 2, level: 9 } toggleService.send(levelUpdater.update(-100)); diff --git a/docs/zh/packages/xstate-svelte/index.md b/docs/zh/packages/xstate-svelte/index.md index 85b1d10b58..88b006f2f5 100644 --- a/docs/zh/packages/xstate-svelte/index.md +++ b/docs/zh/packages/xstate-svelte/index.md @@ -205,10 +205,10 @@ A function that returns [Svelte store](https://svelte.dev/docs#svelte_store) rep $: $service.context.count && withoutSelector++; - - @@ -362,7 +362,7 @@ export const toggleService = interpret(toggleMachine).start(); import { toggleService } from './service'; - ); diff --git a/docs/zh/recipes/svelte.md b/docs/zh/recipes/svelte.md index 2d6c15bb5d..456523da35 100644 --- a/docs/zh/recipes/svelte.md +++ b/docs/zh/recipes/svelte.md @@ -57,7 +57,7 @@ export const toggleMachine = createMachine({ }).start() - ``` @@ -74,7 +74,7 @@ The toggleService has a `.subscribe` function that is similar to Svelte stores, const toggleService = interpret(toggleMachine).start(); - ``` diff --git a/examples/fetch/src/index.ts b/examples/fetch/src/index.ts index 994dff7ba7..89a51d5e8a 100644 --- a/examples/fetch/src/index.ts +++ b/examples/fetch/src/index.ts @@ -18,4 +18,4 @@ const fetchService = interpret(fetchMachine) }) .start(); -fetchService.send('FETCH'); +fetchService.send({ type: 'FETCH' }); diff --git a/examples/template-js/src/main.js b/examples/template-js/src/main.js index ef33e720e3..1225af3b30 100644 --- a/examples/template-js/src/main.js +++ b/examples/template-js/src/main.js @@ -21,5 +21,5 @@ const service = interpret(toggleMachine).onTransition((state) => { service.start(); button?.addEventListener('click', () => { - service.send('TOGGLE'); + service.send({ type: 'TOGGLE' }); }); diff --git a/examples/template-ts/src/main.ts b/examples/template-ts/src/main.ts index 338c43926d..ecd6b79715 100644 --- a/examples/template-ts/src/main.ts +++ b/examples/template-ts/src/main.ts @@ -21,5 +21,5 @@ const service = interpret(machine).onTransition((state) => { service.start(); button?.addEventListener('click', () => { - service.send('TOGGLE'); + service.send({ type: 'TOGGLE' }); }); diff --git a/examples/todo-mvc-react/src/todos.machine.ts b/examples/todo-mvc-react/src/todos.machine.ts index 72c6374385..2865a5983f 100644 --- a/examples/todo-mvc-react/src/todos.machine.ts +++ b/examples/todo-mvc-react/src/todos.machine.ts @@ -114,12 +114,14 @@ export const todosMachine = todosModel.createMachine({ }, 'MARK.completed': { actions: (context) => { - context.todos.forEach((todo) => todo.ref.send('SET_COMPLETED')); + context.todos.forEach((todo) => + todo.ref.send({ type: 'SET_COMPLETED' }) + ); } }, 'MARK.active': { actions: (context) => { - context.todos.forEach((todo) => todo.ref.send('SET_ACTIVE')); + context.todos.forEach((todo) => todo.ref.send({ type: 'SET_ACTIVE' })); } }, CLEAR_COMPLETED: { diff --git a/examples/todo-mvc-svelte/src/todos.machine.ts b/examples/todo-mvc-svelte/src/todos.machine.ts index 344d48c084..064e31a60c 100644 --- a/examples/todo-mvc-svelte/src/todos.machine.ts +++ b/examples/todo-mvc-svelte/src/todos.machine.ts @@ -110,12 +110,14 @@ export const todosMachine = todosModel.createMachine({ }, 'MARK.completed': { actions: (context) => { - context.todos.forEach((todo) => todo.ref.send('SET_COMPLETED')); + context.todos.forEach((todo) => + todo.ref.send({ type: 'SET_COMPLETED' }) + ); } }, 'MARK.active': { actions: (context) => { - context.todos.forEach((todo) => todo.ref.send('SET_ACTIVE')); + context.todos.forEach((todo) => todo.ref.send({ type: 'SET_ACTIVE' })); } }, CLEAR_COMPLETED: { diff --git a/examples/todo-mvc-vue/src/todos.machine.ts b/examples/todo-mvc-vue/src/todos.machine.ts index b401ebc48b..3d4ec0f39b 100644 --- a/examples/todo-mvc-vue/src/todos.machine.ts +++ b/examples/todo-mvc-vue/src/todos.machine.ts @@ -109,12 +109,14 @@ export const todosMachine = todosModel.createMachine({ }, 'MARK.completed': { actions: (context) => { - context.todos.forEach((todo) => todo.ref.send('SET_COMPLETED')); + context.todos.forEach((todo) => + todo.ref.send({ type: 'SET_COMPLETED' }) + ); } }, 'MARK.active': { actions: (context) => { - context.todos.forEach((todo) => todo.ref.send('SET_ACTIVE')); + context.todos.forEach((todo) => todo.ref.send({ type: 'SET_ACTIVE' })); } }, CLEAR_COMPLETED: { diff --git a/packages/core/README.md b/packages/core/README.md index 959ded4fbd..8d0f546716 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -52,10 +52,10 @@ const toggleService = interpret(toggleMachine) .start(); // => 'inactive' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'active' -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // => 'inactive' ``` @@ -116,7 +116,8 @@ const lightMachine = createMachine({ const currentState = 'green'; -const nextState = lightMachine.transition(currentState, 'TIMER').value; +const nextState = lightMachine.transition(currentState, { type: 'TIMER' }) + .value; // => 'yellow' ``` @@ -170,12 +171,13 @@ const lightMachine = createMachine({ const currentState = 'yellow'; -const nextState = lightMachine.transition(currentState, 'TIMER').value; +const nextState = lightMachine.transition(currentState, { type: 'TIMER' }) + .value; // => { // red: 'walk' // } -lightMachine.transition('red.walk', 'PED_TIMER').value; +lightMachine.transition('red.walk', { type: 'PED_TIMER' }).value; // => { // red: 'wait' // } @@ -185,15 +187,18 @@ lightMachine.transition('red.walk', 'PED_TIMER').value; ```js // ... -const waitState = lightMachine.transition({ red: 'walk' }, 'PED_TIMER').value; +const waitState = lightMachine.transition( + { red: 'walk' }, + { type: 'PED_TIMER' } +).value; // => { red: 'wait' } -lightMachine.transition(waitState, 'PED_TIMER').value; +lightMachine.transition(waitState, { type: 'PED_TIMER' }).value; // => { red: 'stop' } -lightMachine.transition({ red: 'stop' }, 'TIMER').value; +lightMachine.transition({ red: 'stop' }, { type: 'TIMER' }).value; // => 'green' ``` @@ -257,7 +262,8 @@ const wordMachine = createMachine({ } }); -const boldState = wordMachine.transition('bold.off', 'TOGGLE_BOLD').value; +const boldState = wordMachine.transition('bold.off', { type: 'TOGGLE_BOLD' }) + .value; // { // bold: 'on', @@ -273,7 +279,7 @@ const nextState = wordMachine.transition( underline: 'on', list: 'bullets' }, - 'TOGGLE_ITALICS' + { type: 'TOGGLE_ITALICS' } ).value; // { @@ -308,21 +314,25 @@ const paymentMachine = createMachine({ } }); -const checkState = paymentMachine.transition('method.cash', 'SWITCH_CHECK'); +const checkState = paymentMachine.transition('method.cash', { + type: 'SWITCH_CHECK' +}); // => State { // value: { method: 'check' }, // history: State { ... } // } -const reviewState = paymentMachine.transition(checkState, 'NEXT'); +const reviewState = paymentMachine.transition(checkState, { type: 'NEXT' }); // => State { // value: 'review', // history: State { ... } // } -const previousState = paymentMachine.transition(reviewState, 'PREVIOUS').value; +const previousState = paymentMachine.transition(reviewState, { + type: 'PREVIOUS' +}).value; // => { method: 'check' } ``` diff --git a/packages/core/src/State.ts b/packages/core/src/State.ts index 2a08a00515..c099e6d1ed 100644 --- a/packages/core/src/State.ts +++ b/packages/core/src/State.ts @@ -14,7 +14,6 @@ import type { MachineContext, Prop, SCXML, - SimpleEventsOf, StateConfig, StateValue, TransitionDefinition @@ -225,7 +224,7 @@ export class State< * @param event The event to test * @returns Whether the event will cause a transition */ - public can(event: TEvent | SimpleEventsOf['type']): boolean { + public can(event: TEvent): boolean { if (IS_PRODUCTION) { warn( !!this.machine, diff --git a/packages/core/src/StateMachine.ts b/packages/core/src/StateMachine.ts index de0b5db93c..7ddd8a4383 100644 --- a/packages/core/src/StateMachine.ts +++ b/packages/core/src/StateMachine.ts @@ -31,7 +31,6 @@ import type { import type { ActorMap, BaseActionObject, - Event, EventObject, InternalMachineImplementations, MachineConfig, @@ -257,7 +256,7 @@ export class StateMachine< public transition( state: StateValue | State = this .initialState, - event: Event | SCXML.Event, + event: TEvent | SCXML.Event, actorCtx?: ActorContext> ): State { const currentState = @@ -287,9 +286,9 @@ export class StateMachine< */ public microstep( state: State = this.initialState, - event: Event | SCXML.Event, - actorCtx?: ActorContext - ): State[] { + event: TEvent | SCXML.Event, + actorCtx?: ActorContext | undefined + ): Array> { const scxmlEvent = toSCXMLEvent(event); const { microstates } = macrostep(state, scxmlEvent, actorCtx); diff --git a/packages/core/src/StateNode.ts b/packages/core/src/StateNode.ts index 3601257beb..5a1e5b447f 100644 --- a/packages/core/src/StateNode.ts +++ b/packages/core/src/StateNode.ts @@ -1,5 +1,4 @@ import { - getEventType, mapValues, flatten, toArray, @@ -10,7 +9,6 @@ import { createInvokeId } from './utils'; import type { - Event, EventObject, HistoryStateNodeConfig, StateNodeDefinition, @@ -327,10 +325,8 @@ export class StateNode< * * @param event The event in question */ - public handles(event: Event): boolean { - const eventType = getEventType(event); - - return this.events.includes(eventType); + public handles(event: TEvent): boolean { + return this.events.includes(event.type); } public next( diff --git a/packages/core/src/actions/raise.ts b/packages/core/src/actions/raise.ts index cc745e7d3e..62dad58390 100644 --- a/packages/core/src/actions/raise.ts +++ b/packages/core/src/actions/raise.ts @@ -1,4 +1,4 @@ -import { Event, EventObject, RaiseActionObject } from '../types'; +import { EventObject, RaiseActionObject } from '../types'; import * as actionTypes from '../actionTypes'; import { toSCXMLEvent } from '../utils'; import { createDynamicAction } from '../../actions/dynamicAction'; @@ -12,7 +12,7 @@ import { BaseDynamicActionObject } from '..'; */ export function raise( - event: Event + event: TEvent ): BaseDynamicActionObject< any, TEvent, diff --git a/packages/core/src/actions/send.ts b/packages/core/src/actions/send.ts index b8f0a4a7af..70eab6c911 100644 --- a/packages/core/src/actions/send.ts +++ b/packages/core/src/actions/send.ts @@ -1,5 +1,4 @@ import { - Event, EventObject, SendActionParams, SpecialTargets, @@ -8,13 +7,7 @@ import { MachineContext } from '../types'; import { send as sendActionType } from '../actionTypes'; -import { - getEventType, - isFunction, - isString, - toEventObject, - toSCXMLEvent -} from '../utils'; +import { isFunction, isString, toSCXMLEvent } from '../utils'; import { createDynamicAction } from '../../actions/dynamicAction'; import { AnyActorRef, @@ -43,7 +36,7 @@ export function send< TEvent extends EventObject, TSentEvent extends EventObject = AnyEventObject >( - event: Event | SendExpr, + event: TSentEvent | SendExpr, options?: SendActionOptions ): BaseDynamicActionObject< TContext, @@ -51,9 +44,7 @@ export function send< SendActionObject, SendActionParams > { - const eventOrExpr = isFunction(event) - ? event - : toEventObject(event); + const eventOrExpr = isFunction(event) ? event : event; return createDynamicAction< TContext, @@ -71,7 +62,7 @@ export function send< ? options.id : isFunction(event) ? event.name - : (getEventType(event) as string) + : event.type }, ({ params }, ctx, _event, { machine, actorContext, state }) => { const meta = { @@ -151,7 +142,7 @@ export function sendParent< TEvent extends EventObject, TSentEvent extends EventObject = AnyEventObject >( - event: Event | SendExpr, + event: TSentEvent | SendExpr, options?: SendActionOptions ) { return send(event, { @@ -171,7 +162,7 @@ export function respond< TEvent extends EventObject, TSentEvent extends EventObject = AnyEventObject >( - event: Event | SendExpr, + event: TEvent | SendExpr, options?: SendActionOptions ) { return send(event, { diff --git a/packages/core/src/actors.ts b/packages/core/src/actors.ts index 3102a24077..e72375f47d 100644 --- a/packages/core/src/actors.ts +++ b/packages/core/src/actors.ts @@ -3,7 +3,6 @@ import type { Subscribable, Subscription, Lazy, - Sender, Receiver, Behavior, ActorContext, @@ -118,7 +117,7 @@ export function fromCallback( dispose: undefined as Promise | (() => void) | void }; - const sender: Sender = (e) => { + const sender = (e) => { if (state.canceled) { return state; } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 9755441816..f520f6cbb0 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -31,7 +31,6 @@ export * from './types'; export { matchesState, pathToStateValue, - toEventObject, toObserver, toSCXMLEvent } from './utils'; diff --git a/packages/core/src/interpreter.ts b/packages/core/src/interpreter.ts index 0f5f849d55..c68fa6646b 100644 --- a/packages/core/src/interpreter.ts +++ b/packages/core/src/interpreter.ts @@ -13,7 +13,6 @@ import { IS_PRODUCTION } from './environment'; import { Mailbox } from './Mailbox'; import { registry } from './registry'; import { AreAllImplementationsAssumedToBeProvided } from './typegenTypes'; -import type { PayloadSender } from './types'; import { ActorRef, DoneEvent, @@ -26,7 +25,7 @@ import { StateValue, Subscription } from './types'; -import { toEventObject, toObserver, toSCXMLEvent, warn } from './utils'; +import { toObserver, toSCXMLEvent, warn } from './utils'; import { symbolObservable } from './symbolObservable'; import { evict } from './memo'; import { doneInvoke, error } from './actions'; @@ -156,6 +155,10 @@ export class Interpreter< this._deferred.push(fn); } }; + + // Ensure that the send method is bound to this interpreter instance + // if destructured + this.send = this.send.bind(this); } // array of functions to defer @@ -393,9 +396,8 @@ export class Interpreter< * * @param event The event(s) to send */ - public send: PayloadSender = (event, payload?): void => { - const eventObject = toEventObject(event, payload); - const _event = toSCXMLEvent(eventObject); + public send(event: TEvent | SCXML.Event) { + const _event = toSCXMLEvent(event); if (this.status === InterpreterStatus.Stopped) { // do nothing @@ -429,7 +431,7 @@ export class Interpreter< } this.mailbox.enqueue(_event); - }; + } // TODO: remove private forward(event: SCXML.Event): void { diff --git a/packages/core/src/patterns.ts b/packages/core/src/patterns.ts index 5612164ddc..b2fbedb39f 100644 --- a/packages/core/src/patterns.ts +++ b/packages/core/src/patterns.ts @@ -1,11 +1,9 @@ import { AtomicStateNodeConfig, StatesConfig, - Event, EventObject, StateNodeConfig } from './types'; -import { toEventObject } from './utils'; export function toggle( onState: string, @@ -23,13 +21,13 @@ export function toggle( } interface SequencePatternOptions { - nextEvent: Event | undefined; - prevEvent: Event | undefined; + nextEvent: TEvent | undefined; + prevEvent: TEvent | undefined; } const defaultSequencePatternOptions = { - nextEvent: 'NEXT', - prevEvent: 'PREV' + nextEvent: { type: 'NEXT' }, + prevEvent: { type: 'PREV' } }; export function sequence( @@ -44,11 +42,11 @@ export function sequence( const nextEventObject = resolvedOptions.nextEvent === undefined ? undefined - : toEventObject(resolvedOptions.nextEvent); + : resolvedOptions.nextEvent; const prevEventObject = resolvedOptions.prevEvent === undefined ? undefined - : toEventObject(resolvedOptions.prevEvent); + : resolvedOptions.prevEvent; items.forEach((item, i) => { const state: StateNodeConfig = { diff --git a/packages/core/src/scxml.ts b/packages/core/src/scxml.ts index b65914e093..792928d38b 100644 --- a/packages/core/src/scxml.ts +++ b/packages/core/src/scxml.ts @@ -140,7 +140,7 @@ function mapAction< >(element: XMLElement): BaseActionObject { switch (element.name) { case 'raise': { - return raise(element.attributes!.event! as string); + return raise({ type: element.attributes!.event! } as TEvent); } case 'assign': { return assign((context, e, meta) => { @@ -168,7 +168,7 @@ return ${element.attributes!.sendidexpr}; case 'send': { const { event, eventexpr, target, id } = element.attributes!; - let convertedEvent: TEvent['type'] | SendExpr; + let convertedEvent: TEvent | SendExpr; let convertedDelay: number | DelayExpr | undefined; const params = @@ -183,7 +183,7 @@ return ${element.attributes!.sendidexpr}; }, ''); if (event && !params) { - convertedEvent = event as TEvent['type']; + convertedEvent = { type: event } as TEvent; } else { convertedEvent = (context, _ev, meta) => { const fnBody = ` diff --git a/packages/core/src/stateUtils.ts b/packages/core/src/stateUtils.ts index f04e18ad45..73be4538cd 100644 --- a/packages/core/src/stateUtils.ts +++ b/packages/core/src/stateUtils.ts @@ -322,7 +322,7 @@ export function getDelayedTransitions< ) => { const delayRef = isFunction(delay) ? `${stateNode.id}:delay[${i}]` : delay; const eventType = after(delayRef, stateNode.id); - stateNode.entry.push(send(eventType, { delay })); + stateNode.entry.push(send({ type: eventType }, { delay })); stateNode.exit.push(cancel(eventType)); return eventType; }; diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index cd44c06546..3a8f59ec73 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -100,11 +100,6 @@ export interface BaseDynamicActionObject< export type MachineContext = Record; -/** - * The specified string event types or the specified event objects. - */ -export type Event = TEvent['type'] | TEvent; - export interface ActionMeta< TContext extends MachineContext, TEvent extends EventObject, @@ -343,39 +338,12 @@ export type Transition< | TransitionConfig | ConditionalTransitionConfig; -type ExcludeType = { [K in Exclude]: A[K] }; - -type ExtractExtraParameters = A extends { type: T } - ? ExcludeType - : never; - type ExtractWithSimpleSupport = T extends any ? { type: T['type'] } extends T ? T : never : never; -type NeverIfEmpty = {} extends T ? never : T; - -export interface PayloadSender { - /** - * Send an event object or just the event type, if the event has no other payload - */ - ( - event: - | SCXML.Event - | TEvent - | ExtractWithSimpleSupport['type'] - ): void; - /** - * Send an event type and its payload - */ - ( - eventType: K, - payload: NeverIfEmpty> - ): void; -} - export type Receiver = ( listener: { bivarianceHack(event: TEvent): void; @@ -386,7 +354,7 @@ export type InvokeCallback< TEvent extends EventObject = AnyEventObject, TSentEvent extends EventObject = AnyEventObject > = ( - callback: Sender, + callback: (event: TSentEvent) => void, onReceive: Receiver ) => (() => void) | Promise | void; @@ -1738,11 +1706,9 @@ export interface BaseActorRef { export interface ActorLike extends Subscribable { - send: Sender; + send: (event: TEvent) => void; } -export type Sender = (event: TEvent) => void; - export interface ActorRef extends Subscribable, InteropObservable { @@ -1914,13 +1880,6 @@ export type EventFrom< TEvent extends EventObject = ResolveEventType > = IsNever extends true ? TEvent : ExtractEvent; -/** - * Events that do not require payload - */ -export type SimpleEventsOf< - TEvent extends EventObject -> = ExtractWithSimpleSupport; - export type ContextFrom = ReturnTypeOrValue extends infer R ? R extends StateMachine< infer TContext, diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 48161a967c..16af78e863 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -6,7 +6,6 @@ import type { StateNode } from './StateNode'; import type { Behavior, BehaviorCreator, - Event, EventObject, EventType, InvokeConfig, @@ -60,20 +59,6 @@ export function matchesState( }); } -export function getEventType( - event: Event -): TEvent['type'] { - try { - return isString(event) || typeof event === 'number' - ? `${event}` - : (event as TEvent).type; - } catch (e) { - throw new Error( - 'Events must be strings or objects with a string event.type property.' - ); - } -} - export function toStatePath( stateId: string | string[], delimiter: string @@ -377,21 +362,10 @@ export const uniqueId = (() => { }; })(); -export function toEventObject( - event: Event, - payload?: Record -): TEvent { - if (isString(event)) { - return { type: event, ...payload } as TEvent; - } - - return event; -} - export function isSCXMLEvent( - event: Event | SCXML.Event + event: TEvent | SCXML.Event ): event is SCXML.Event { - return !isString(event) && '$$type' in event && event.$$type === 'scxml'; + return '$$type' in event && event.$$type === 'scxml'; } export function isSCXMLErrorEvent( @@ -404,18 +378,16 @@ export function isSCXMLErrorEvent( } export function toSCXMLEvent( - event: Event | SCXML.Event, + event: TEvent | SCXML.Event, scxmlEvent?: Partial> ): SCXML.Event { if (isSCXMLEvent(event)) { return event as SCXML.Event; } - const eventObject = toEventObject(event as Event); - return { - name: eventObject.type, - data: eventObject, + name: event.type, + data: event, $$type: 'scxml', type: 'external', ...scxmlEvent diff --git a/packages/core/test/actionCreators.test.ts b/packages/core/test/actionCreators.test.ts index f0286d38e2..e47f80a02b 100644 --- a/packages/core/test/actionCreators.test.ts +++ b/packages/core/test/actionCreators.test.ts @@ -5,7 +5,7 @@ import { toSCXMLEvent } from '../src/utils'; describe('action creators', () => { describe('send()', () => { it('should accept a string event', () => { - const action = send('foo'); + const action = send({ type: 'foo' }); expect(action.params).toEqual( expect.objectContaining({ to: undefined, @@ -29,7 +29,7 @@ describe('action creators', () => { }); it('should accept an id option', () => { - const action = send('foo', { id: 'foo-id' }); + const action = send({ type: 'foo' }, { id: 'foo-id' }); expect(action.params).toEqual( expect.objectContaining({ to: undefined, @@ -41,7 +41,7 @@ describe('action creators', () => { }); it('should accept a delay option', () => { - const action = send('foo', { delay: 1000 }); + const action = send({ type: 'foo' }, { delay: 1000 }); expect(action.params).toEqual( expect.objectContaining({ to: undefined, @@ -56,9 +56,12 @@ describe('action creators', () => { const action = send< { delay: number }, { type: 'EVENT'; value: number } | { type: 'RECEIVED' } - >('RECEIVED', { - delay: (ctx, e) => ctx.delay + ('value' in e ? e.value : 0) - }); + >( + { type: 'RECEIVED' }, + { + delay: (ctx, e) => ctx.delay + ('value' in e ? e.value : 0) + } + ); const resolvedAction = action.resolve( action, diff --git a/packages/core/test/actions.test.ts b/packages/core/test/actions.test.ts index 2b7c22a5bd..3c33e3a3b0 100644 --- a/packages/core/test/actions.test.ts +++ b/packages/core/test/actions.test.ts @@ -282,53 +282,65 @@ describe('entry/exit actions', () => { it('should return the entry and exit actions of a transition', () => { expect( - lightMachine.transition('green', 'TIMER').actions.map((a) => a.type) + lightMachine + .transition('green', { type: 'TIMER' }) + .actions.map((a) => a.type) ).toEqual(['exit_green', 'enter_yellow']); }); it('should return the entry and exit actions of a deep transition', () => { expect( - lightMachine.transition('yellow', 'TIMER').actions.map((a) => a.type) + lightMachine + .transition('yellow', { type: 'TIMER' }) + .actions.map((a) => a.type) ).toEqual(['exit_yellow', 'enter_red', 'enter_walk']); }); it('should return the entry and exit actions of a nested transition', () => { expect( lightMachine - .transition({ red: 'walk' }, 'PED_COUNTDOWN') + .transition({ red: 'walk' }, { type: 'PED_COUNTDOWN' }) .actions.map((a) => a.type) ).toEqual(['exit_walk', 'enter_wait']); }); it('should not have actions for unhandled events (shallow)', () => { expect( - lightMachine.transition('green', 'FAKE').actions.map((a) => a.type) + lightMachine + .transition('green', { type: 'FAKE' }) + .actions.map((a) => a.type) ).toEqual([]); }); it('should not have actions for unhandled events (deep)', () => { expect( - lightMachine.transition('red', 'FAKE').actions.map((a) => a.type) + lightMachine + .transition('red', { type: 'FAKE' }) + .actions.map((a) => a.type) ).toEqual([]); }); it('should exit and enter the state for self-transitions (shallow)', () => { expect( - lightMachine.transition('green', 'NOTHING').actions.map((a) => a.type) + lightMachine + .transition('green', { type: 'NOTHING' }) + .actions.map((a) => a.type) ).toEqual(['exit_green', 'enter_green']); }); it('should exit and enter the state for self-transitions (deep)', () => { // 'red' state resolves to 'red.walk' expect( - lightMachine.transition('red', 'NOTHING').actions.map((a) => a.type) + lightMachine + .transition('red', { type: 'NOTHING' }) + .actions.map((a) => a.type) ).toEqual(['exit_walk', 'exit_red', 'enter_red', 'enter_walk']); }); it('should return actions for parallel machines', () => { expect( parallelMachine - .transition(parallelMachine.initialState, 'CHANGE') + .transition(parallelMachine.initialState, { type: 'CHANGE' }) .actions.map((a) => a.type) ).toEqual([ 'exit_b1', // reverse document order @@ -343,7 +355,9 @@ describe('entry/exit actions', () => { it('should return nested actions in the correct (child to parent) order', () => { expect( - deepMachine.transition({ a: 'a1' }, 'CHANGE').actions.map((a) => a.type) + deepMachine + .transition({ a: 'a1' }, { type: 'CHANGE' }) + .actions.map((a) => a.type) ).toEqual([ 'exit_a1', 'exit_a', @@ -356,20 +370,22 @@ describe('entry/exit actions', () => { it('should ignore parent state actions for same-parent substates', () => { expect( - deepMachine.transition({ a: 'a1' }, 'NEXT').actions.map((a) => a.type) + deepMachine + .transition({ a: 'a1' }, { type: 'NEXT' }) + .actions.map((a) => a.type) ).toEqual(['exit_a1', 'enter_a2']); }); it('should work with function actions', () => { expect( deepMachine - .transition(deepMachine.initialState, 'NEXT_FN') + .transition(deepMachine.initialState, { type: 'NEXT_FN' }) .actions.map((action) => action.type) ).toEqual(['exit_a1', 'enter_a3_fn']); expect( deepMachine - .transition({ a: 'a3' }, 'NEXT') + .transition({ a: 'a3' }, { type: 'NEXT' }) .actions.map((action) => action.type) ).toEqual(['exit_a3_fn', 'do_a3_to_a2', 'enter_a2']); }); @@ -377,10 +393,10 @@ describe('entry/exit actions', () => { it('should exit children of parallel state nodes', () => { const stateB = parallelMachine2.transition( parallelMachine2.initialState, - 'to-B' + { type: 'to-B' } ); - const stateD2 = parallelMachine2.transition(stateB, 'to-D2'); - const stateA = parallelMachine2.transition(stateD2, 'to-A'); + const stateD2 = parallelMachine2.transition(stateB, { type: 'to-D2' }); + const stateA = parallelMachine2.transition(stateD2, { type: 'to-A' }); expect(stateA.actions.map((action) => action.type)).toEqual(['D2 Exit']); }); @@ -408,7 +424,7 @@ describe('entry/exit actions', () => { const service = interpret(machine).start(); actual.length = 0; - service.send('UPDATE'); + service.send({ type: 'UPDATE' }); expect(actual).toEqual(['loaded entry']); }); @@ -508,13 +524,14 @@ describe('entry/exit actions', () => { it('with a relative transition', () => { expect( - pingPong.transition({ ping: 'foo' }, 'TACK').actions + pingPong.transition({ ping: 'foo' }, { type: 'TACK' }).actions ).toHaveLength(0); }); it('with an absolute transition', () => { expect( - pingPong.transition({ ping: 'foo' }, 'ABSOLUTE_TACK').actions + pingPong.transition({ ping: 'foo' }, { type: 'ABSOLUTE_TACK' }) + .actions ).toHaveLength(0); }); }); @@ -529,40 +546,48 @@ describe('entry/exit actions', () => { it('should return the entry and exit actions of a transition', () => { expect( - newLightMachine.transition('green', 'TIMER').actions.map((a) => a.type) + newLightMachine + .transition('green', { type: 'TIMER' }) + .actions.map((a) => a.type) ).toEqual(['exit_green', 'enter_yellow']); }); it('should return the entry and exit actions of a deep transition', () => { expect( - newLightMachine.transition('yellow', 'TIMER').actions.map((a) => a.type) + newLightMachine + .transition('yellow', { type: 'TIMER' }) + .actions.map((a) => a.type) ).toEqual(['exit_yellow', 'enter_red', 'enter_walk']); }); it('should return the entry and exit actions of a nested transition', () => { expect( newLightMachine - .transition({ red: 'walk' }, 'PED_COUNTDOWN') + .transition({ red: 'walk' }, { type: 'PED_COUNTDOWN' }) .actions.map((a) => a.type) ).toEqual(['exit_walk', 'enter_wait']); }); it('should not have actions for unhandled events (shallow)', () => { expect( - newLightMachine.transition('green', 'FAKE').actions.map((a) => a.type) + newLightMachine + .transition('green', { type: 'FAKE' }) + .actions.map((a) => a.type) ).toEqual([]); }); it('should not have actions for unhandled events (deep)', () => { expect( - newLightMachine.transition('red', 'FAKE').actions.map((a) => a.type) + newLightMachine + .transition('red', { type: 'FAKE' }) + .actions.map((a) => a.type) ).toEqual([]); }); it('should exit and enter the state for self-transitions (shallow)', () => { expect( newLightMachine - .transition('green', 'NOTHING') + .transition('green', { type: 'NOTHING' }) .actions.map((a) => a.type) ).toEqual(['exit_green', 'enter_green']); }); @@ -570,7 +595,9 @@ describe('entry/exit actions', () => { it('should exit and enter the state for self-transitions (deep)', () => { // 'red' state resolves to 'red.walk' expect( - newLightMachine.transition('red', 'NOTHING').actions.map((a) => a.type) + newLightMachine + .transition('red', { type: 'NOTHING' }) + .actions.map((a) => a.type) ).toEqual(['exit_walk', 'exit_red', 'enter_red', 'enter_walk']); }); @@ -600,7 +627,7 @@ describe('entry/exit actions', () => { const service = interpret(m).start(); - service.send('EV'); + service.send({ type: 'EV' }); expect(actual).toEqual(['a11.exit']); }); @@ -635,7 +662,7 @@ describe('entry/exit actions', () => { expect( parallelMachineWithEntry - .transition('start', 'ENTER_PARALLEL') + .transition('start', { type: 'ENTER_PARALLEL' }) .actions.map((a) => a.type) ).toEqual(['enter_p1', 'enter_inner']); }); @@ -675,7 +702,7 @@ describe('entry/exit actions', () => { const service = interpret(machine).start(); actions.length = 0; - service.send('FOO'); + service.send({ type: 'FOO' }); expect(actions).toEqual([ 'exit camera', @@ -718,7 +745,7 @@ describe('entry/exit actions', () => { Promise.resolve() .then(() => { - service.send('WHATEVER'); + service.send({ type: 'WHATEVER' }); }) .then(() => { expect(actual).toEqual(['entered one', 'got WHATEVER']); @@ -1058,7 +1085,7 @@ describe('entry/exit actions', () => { initial: 'idle', states: { idle: { - exit: sendParent('EXIT') + exit: sendParent({ type: 'EXIT' }) } } }); @@ -1085,7 +1112,7 @@ describe('entry/exit actions', () => { initial: 'idle', states: { idle: { - exit: sendParent('EXIT') + exit: sendParent({ type: 'EXIT' }) } } }); @@ -1127,7 +1154,7 @@ describe('entry/exit actions', () => { type: 'final' } }, - exit: sendParent('CHILD_DONE') + exit: sendParent({ type: 'CHILD_DONE' }) }); const parent = createMachine({ @@ -1483,7 +1510,7 @@ describe('initial actions', () => { }); it('should support initial actions from transition', () => { - const nextState = machine.transition(undefined, 'NEXT'); + const nextState = machine.transition(undefined, { type: 'NEXT' }); expect(nextState.actions.map((a) => a.type)).toEqual([ 'entryB', 'initialFoo', @@ -1492,7 +1519,7 @@ describe('initial actions', () => { }); it('should support initial actions from transition with target ID', () => { - const nextState = machine.transition('b', 'NEXT'); + const nextState = machine.transition('b', { type: 'NEXT' }); expect(nextState.actions.map((a) => a.type)).toEqual([ 'entryC', 'initialBar', @@ -1518,10 +1545,10 @@ describe('actions on invalid transition', () => { }); it('should not recall previous actions', () => { - const nextState = stopMachine.transition('idle', 'STOP'); - expect(stopMachine.transition(nextState, 'INVALID').actions).toHaveLength( - 0 - ); + const nextState = stopMachine.transition('idle', { type: 'STOP' }); + expect( + stopMachine.transition(nextState, { type: 'INVALID' }).actions + ).toHaveLength(0); }); }); @@ -1573,7 +1600,7 @@ describe('actions config', () => { it('should reference actions defined in actions parameter of machine options', () => { const { initialState } = simpleMachine; - const nextState = simpleMachine.transition(initialState, 'E'); + const nextState = simpleMachine.transition(initialState, { type: 'E' }); expect(nextState.actions.map((a) => a.type)).toEqual( expect.arrayContaining(['definedAction', 'undefinedAction']) @@ -1625,7 +1652,7 @@ describe('actions config', () => { } } ); - const state = machine.transition('a', 'EVENT'); + const state = machine.transition('a', { type: 'EVENT' }); // expect(state.actions).toEqual([ // expect.objectContaining({ @@ -1673,7 +1700,9 @@ describe('actions config', () => { expect(entryCalled).toBe(true); - const inactiveState = anonMachine.transition(initialState, 'EVENT'); + const inactiveState = anonMachine.transition(initialState, { + type: 'EVENT' + }); expect(inactiveState.actions.length).toBe(2); @@ -1799,10 +1828,9 @@ describe('purely defined actions', () => { }); it('should allow for purely defined dynamic actions', () => { - const nextState = dynamicMachine.transition( - dynamicMachine.initialState, - 'EACH' - ); + const nextState = dynamicMachine.transition(dynamicMachine.initialState, { + type: 'EACH' + }); expect(nextState.actions).toEqual([ expect.objectContaining({ @@ -1830,7 +1858,7 @@ describe('forwardTo()', () => { active: { on: { EVENT: { - actions: sendParent('SUCCESS'), + actions: sendParent({ type: 'SUCCESS' }), guard: (_, e) => e.value === 42 } } @@ -1875,7 +1903,7 @@ describe('forwardTo()', () => { active: { on: { EVENT: { - actions: sendParent('SUCCESS'), + actions: sendParent({ type: 'SUCCESS' }), guard: (_, e) => e.value === 42 } } @@ -1926,7 +1954,9 @@ describe('forwardTo()', () => { const service = interpret(machine).start(); - expect(() => service.send('TEST')).toThrowErrorMatchingInlineSnapshot( + expect(() => + service.send({ type: 'TEST' }) + ).toThrowErrorMatchingInlineSnapshot( `"Attempted to forward event to undefined actor. This risks an infinite loop in the sender."` ); }); @@ -1964,7 +1994,9 @@ describe('log()', () => { }); it('should log an expression', () => { - const nextState = logMachine.transition(logMachine.initialState, 'EXPR'); + const nextState = logMachine.transition(logMachine.initialState, { + type: 'EXPR' + }); expect(nextState.actions[0]).toMatchInlineSnapshot(` Object { "params": Object { @@ -2226,7 +2258,7 @@ describe('choose', () => { }); const service = interpret(machine).start(); - service.send('GIVE_ANSWER'); + service.send({ type: 'GIVE_ANSWER' }); expect(service.getSnapshot().context).toEqual({ counter: 101, answer: 42 }); }); @@ -2534,8 +2566,8 @@ describe('assign action order', () => { const service = interpret(machine).start(); - service.send('EV'); - service.send('EV'); + service.send({ type: 'EV' }); + service.send({ type: 'EV' }); expect(captured).toEqual([1, 2]); }); diff --git a/packages/core/test/activities.test.ts b/packages/core/test/activities.test.ts index 74149aa7c1..40a41e33f0 100644 --- a/packages/core/test/activities.test.ts +++ b/packages/core/test/activities.test.ts @@ -65,7 +65,7 @@ describe('activities with guarded transitions', () => { const service = interpret(machine).start(); - service.send('E'); + service.send({ type: 'E' }); }); }); @@ -99,8 +99,8 @@ describe('remembering activities', () => { }) ).start(); - service.send('E'); - service.send('IGNORE'); + service.send({ type: 'E' }); + service.send({ type: 'IGNORE' }); }); }); @@ -132,8 +132,8 @@ describe('activities', () => { ); service.start(); - service.send('TIMER'); // yellow - service.send('TIMER'); // red + service.send({ type: 'TIMER' }); // yellow + service.send({ type: 'TIMER' }); // red }); it('identifies start activities for child states and active activities', (done) => { @@ -149,9 +149,9 @@ describe('activities', () => { ); service.start(); - service.send('TIMER'); // yellow - service.send('TIMER'); // red.walk - service.send('PED_WAIT'); // red.wait + service.send({ type: 'TIMER' }); // yellow + service.send({ type: 'TIMER' }); // red.walk + service.send({ type: 'PED_WAIT' }); // red.wait }); it('identifies stop activities for child states', (done) => { @@ -169,10 +169,10 @@ describe('activities', () => { ); service.start(); - service.send('TIMER'); // yellow - service.send('TIMER'); // red.walk - service.send('PED_WAIT'); // red.wait - service.send('PED_STOP'); + service.send({ type: 'TIMER' }); // yellow + service.send({ type: 'TIMER' }); // red.walk + service.send({ type: 'PED_WAIT' }); // red.wait + service.send({ type: 'PED_STOP' }); }); it('identifies multiple stop activities for child and parent states', (done) => { @@ -198,11 +198,11 @@ describe('activities', () => { ); service.start(); - service.send('TIMER'); // yellow - service.send('TIMER'); // red.walk - service.send('PED_WAIT'); // red.wait - service.send('PED_STOP'); // red.stop - service.send('TIMER'); // green + service.send({ type: 'TIMER' }); // yellow + service.send({ type: 'TIMER' }); // red.walk + service.send({ type: 'PED_WAIT' }); // red.wait + service.send({ type: 'PED_STOP' }); // red.stop + service.send({ type: 'TIMER' }); // green }); }); @@ -322,7 +322,7 @@ describe('transient activities', () => { }) ).start(); - service.send('A'); + service.send({ type: 'A' }); }); it('should have kept same activities', (done) => { @@ -337,7 +337,7 @@ describe('transient activities', () => { }) ).start(); - service.send('C_SIMILAR'); + service.send({ type: 'C_SIMILAR' }); }); it('should have kept same activities after self transition', (done) => { @@ -352,7 +352,7 @@ describe('transient activities', () => { }) ).start(); - service.send('C'); + service.send({ type: 'C' }); }); it('should have stopped after automatic transitions', (done) => { @@ -367,6 +367,6 @@ describe('transient activities', () => { }) ).start(); - service.send('A'); + service.send({ type: 'A' }); }); }); diff --git a/packages/core/test/actor.test.ts b/packages/core/test/actor.test.ts index 7c1b428a37..1fbd7ee474 100644 --- a/packages/core/test/actor.test.ts +++ b/packages/core/test/actor.test.ts @@ -63,7 +63,7 @@ describe('spawning machines', () => { } }, sendPong: { - entry: [sendParent('PONG'), raise('SUCCESS')], + entry: [sendParent({ type: 'PONG' }), raise({ type: 'SUCCESS' })], on: { SUCCESS: 'waitPing' } @@ -87,14 +87,17 @@ describe('spawning machines', () => { assign({ server: (_, __, { spawn }) => spawn(serverMachine) }), - raise('SUCCESS') + raise({ type: 'SUCCESS' }) ], on: { SUCCESS: 'sendPing' } }, sendPing: { - entry: [send('PING', { to: (ctx) => ctx.server! }), raise('SUCCESS')], + entry: [ + send({ type: 'PING' }, { to: (ctx) => ctx.server! }), + raise({ type: 'SUCCESS' }) + ], on: { SUCCESS: 'waitPong' } @@ -148,11 +151,14 @@ describe('spawning machines', () => { }) }, SET_COMPLETE: { - actions: send('SET_COMPLETE', { - to: (ctx, e: Extract) => { - return ctx.todoRefs[e.id]; + actions: send( + { type: 'SET_COMPLETE' }, + { + to: (ctx, e: Extract) => { + return ctx.todoRefs[e.id]; + } } - }) + ) } } }); @@ -168,7 +174,7 @@ describe('spawning machines', () => { it('should spawn referenced machines', (done) => { const childMachine = createMachine({ - entry: sendParent('DONE') + entry: sendParent({ type: 'DONE' }) }); const parentMachine = createMachine( @@ -332,7 +338,7 @@ describe('spawning callbacks', () => { }), on: { START_CB: { - actions: send('START', { to: (ctx) => ctx.callbackRef }) + actions: send({ type: 'START' }, { to: (ctx) => ctx.callbackRef }) }, SEND_BACK: 'success' } @@ -348,7 +354,7 @@ describe('spawning callbacks', () => { }); callbackService.start(); - callbackService.send('START_CB'); + callbackService.send({ type: 'START_CB' }); }); }); @@ -526,7 +532,7 @@ describe('communicating with spawned actors', () => { on: { ACTIVATE: 'active' } }, active: { - entry: respond('EXISTING.DONE') + entry: respond({ type: 'EXISTING.DONE' }) } } }); @@ -552,7 +558,10 @@ describe('communicating with spawned actors', () => { }, after: { 100: { - actions: send('ACTIVATE', { to: (ctx) => ctx.existingRef }) + actions: send( + { type: 'ACTIVATE' }, + { to: (ctx) => ctx.existingRef } + ) } } }, @@ -577,7 +586,7 @@ describe('communicating with spawned actors', () => { on: { ACTIVATE: 'active' } }, active: { - entry: respond('EXISTING.DONE') + entry: respond({ type: 'EXISTING.DONE' }) } } }); @@ -603,7 +612,7 @@ describe('communicating with spawned actors', () => { }, after: { 100: { - actions: send('ACTIVATE', { to: 'existing' }) + actions: send({ type: 'ACTIVATE' }, { to: 'existing' }) } } }, @@ -628,7 +637,7 @@ describe('communicating with spawned actors', () => { on: { ACTIVATE: 'active' } }, active: { - entry: respond('EXISTING.DONE') + entry: respond({ type: 'EXISTING.DONE' }) } } }); @@ -642,13 +651,16 @@ describe('communicating with spawned actors', () => { }, states: { pending: { - entry: send('ACTIVATE', { to: () => existingService }), + entry: send({ type: 'ACTIVATE' }, { to: () => existingService }), on: { 'EXISTING.DONE': 'success' }, after: { 100: { - actions: send('ACTIVATE', { to: (ctx) => ctx.existingRef }) + actions: send( + { type: 'ACTIVATE' }, + { to: (ctx) => ctx.existingRef } + ) } } }, @@ -752,7 +764,7 @@ describe('actors', () => { initial: 'hello', states: { hello: { - entry: sendParent('ping') + entry: sendParent({ type: 'ping' }) } } }); @@ -838,8 +850,8 @@ describe('actors', () => { }) .start(); - countService.send('INC'); - countService.send('INC'); + countService.send({ type: 'INC' }); + countService.send({ type: 'INC' }); }); it('should work with a promise behavior (fulfill)', (done) => { @@ -948,7 +960,7 @@ describe('actors', () => { }), states: { waiting: { - entry: send('PING', { to: (ctx) => ctx.ponger! }), + entry: send({ type: 'PING' }, { to: (ctx) => ctx.ponger! }), invoke: { id: 'ponger', src: pongBehavior @@ -999,7 +1011,7 @@ describe('actors', () => { it('should be able to spawn machines in (lazy) initial context', (done) => { const childMachine = createMachine({ - entry: sendParent('TEST') + entry: sendParent({ type: 'TEST' }) }); const machine = createMachine<{ ref: ActorRef }>({ diff --git a/packages/core/test/after.test.ts b/packages/core/test/after.test.ts index d9384c713b..9af91f5f30 100644 --- a/packages/core/test/after.test.ts +++ b/packages/core/test/after.test.ts @@ -26,10 +26,9 @@ const lightMachine = createMachine({ describe('delayed transitions', () => { it('should transition after delay', () => { - const nextState = lightMachine.transition( - lightMachine.initialState, - after(1000, 'light.green') - ); + const nextState = lightMachine.transition(lightMachine.initialState, { + type: after(1000, 'light.green') + }); expect(nextState.value).toEqual('yellow'); expect(nextState.actions).toMatchInlineSnapshot(` @@ -189,7 +188,7 @@ describe('delayed transitions', () => { } }); - const withAfterState = machine.transition(undefined, 'next'); + const withAfterState = machine.transition(undefined, { type: 'next' }); interpret(machine) .onDone(() => done()) diff --git a/packages/core/test/assign.test.ts b/packages/core/test/assign.test.ts index 96e12648b7..f361aff940 100644 --- a/packages/core/test/assign.test.ts +++ b/packages/core/test/assign.test.ts @@ -94,15 +94,14 @@ describe('assign', () => { it('applies the assignment to the external state (property assignment)', () => { const counterMachine = createCounterMachine(); - const oneState = counterMachine.transition( - counterMachine.initialState, - 'DEC' - ); + const oneState = counterMachine.transition(counterMachine.initialState, { + type: 'DEC' + }); expect(oneState.value).toEqual('counting'); expect(oneState.context).toEqual({ count: -1, foo: 'bar' }); - const twoState = counterMachine.transition(oneState, 'DEC'); + const twoState = counterMachine.transition(oneState, { type: 'DEC' }); expect(twoState.value).toEqual('counting'); expect(twoState.context).toEqual({ count: -2, foo: 'bar' }); @@ -111,15 +110,14 @@ describe('assign', () => { it('applies the assignment to the external state', () => { const counterMachine = createCounterMachine(); - const oneState = counterMachine.transition( - counterMachine.initialState, - 'INC' - ); + const oneState = counterMachine.transition(counterMachine.initialState, { + type: 'INC' + }); expect(oneState.value).toEqual('counting'); expect(oneState.context).toEqual({ count: 1, foo: 'bar' }); - const twoState = counterMachine.transition(oneState, 'INC'); + const twoState = counterMachine.transition(oneState, { type: 'INC' }); expect(twoState.value).toEqual('counting'); expect(twoState.context).toEqual({ count: 2, foo: 'bar' }); @@ -127,59 +125,55 @@ describe('assign', () => { it('applies the assignment to multiple properties (property assignment)', () => { const counterMachine = createCounterMachine(); - const nextState = counterMachine.transition( - counterMachine.initialState, - 'WIN_PROP' - ); + const nextState = counterMachine.transition(counterMachine.initialState, { + type: 'WIN_PROP' + }); expect(nextState.context).toEqual({ count: 100, foo: 'win' }); }); it('applies the assignment to multiple properties (static)', () => { const counterMachine = createCounterMachine(); - const nextState = counterMachine.transition( - counterMachine.initialState, - 'WIN_STATIC' - ); + const nextState = counterMachine.transition(counterMachine.initialState, { + type: 'WIN_STATIC' + }); expect(nextState.context).toEqual({ count: 100, foo: 'win' }); }); it('applies the assignment to multiple properties (static + prop assignment)', () => { const counterMachine = createCounterMachine(); - const nextState = counterMachine.transition( - counterMachine.initialState, - 'WIN_MIX' - ); + const nextState = counterMachine.transition(counterMachine.initialState, { + type: 'WIN_MIX' + }); expect(nextState.context).toEqual({ count: 100, foo: 'win' }); }); it('applies the assignment to multiple properties', () => { const counterMachine = createCounterMachine(); - const nextState = counterMachine.transition( - counterMachine.initialState, - 'WIN' - ); + const nextState = counterMachine.transition(counterMachine.initialState, { + type: 'WIN' + }); expect(nextState.context).toEqual({ count: 100, foo: 'win' }); }); it('applies the assignment to the explicit external state (property assignment)', () => { const machine = createCounterMachine({ count: 50, foo: 'bar' }); - const oneState = machine.transition(undefined, 'DEC'); + const oneState = machine.transition(undefined, { type: 'DEC' }); expect(oneState.value).toEqual('counting'); expect(oneState.context).toEqual({ count: 49, foo: 'bar' }); - const twoState = machine.transition(oneState, 'DEC'); + const twoState = machine.transition(oneState, { type: 'DEC' }); expect(twoState.value).toEqual('counting'); expect(twoState.context).toEqual({ count: 48, foo: 'bar' }); const machine2 = createCounterMachine({ count: 100, foo: 'bar' }); - const threeState = machine2.transition(undefined, 'DEC'); + const threeState = machine2.transition(undefined, { type: 'DEC' }); expect(threeState.value).toEqual('counting'); expect(threeState.context).toEqual({ count: 99, foo: 'bar' }); @@ -187,19 +181,19 @@ describe('assign', () => { it('applies the assignment to the explicit external state', () => { const machine = createCounterMachine({ count: 50, foo: 'bar' }); - const oneState = machine.transition(undefined, 'INC'); + const oneState = machine.transition(undefined, { type: 'INC' }); expect(oneState.value).toEqual('counting'); expect(oneState.context).toEqual({ count: 51, foo: 'bar' }); - const twoState = machine.transition(oneState, 'INC'); + const twoState = machine.transition(oneState, { type: 'INC' }); expect(twoState.value).toEqual('counting'); expect(twoState.context).toEqual({ count: 52, foo: 'bar' }); const machine2 = createCounterMachine({ count: 102, foo: 'bar' }); - const threeState = machine2.transition(undefined, 'INC'); + const threeState = machine2.transition(undefined, { type: 'INC' }); expect(threeState.value).toEqual('counting'); expect(threeState.context).toEqual({ count: 103, foo: 'bar' }); @@ -209,7 +203,9 @@ describe('assign', () => { const counterMachine = createCounterMachine(); const { initialState } = counterMachine; - const nextState = counterMachine.transition(initialState, 'FAKE_EVENT'); + const nextState = counterMachine.transition(initialState, { + type: 'FAKE_EVENT' + }); expect(nextState.context).toBeDefined(); expect(nextState.context).toEqual({ count: 0, foo: 'bar' }); @@ -219,7 +215,9 @@ describe('assign', () => { const counterMachine = createCounterMachine(); const { initialState } = counterMachine; - const nextState = counterMachine.transition(initialState, 'SET_MAYBE'); + const nextState = counterMachine.transition(initialState, { + type: 'SET_MAYBE' + }); expect(nextState.context.maybe).toBeDefined(); expect(nextState.context).toEqual({ @@ -300,7 +298,7 @@ describe('assign meta', () => { it('should provide the state in regular transitions (prop assigner)', () => { const { initialState } = machine; - const nextState = machine.transition(initialState, 'NEXT'); + const nextState = machine.transition(initialState, { type: 'NEXT' }); expect(nextState.context).toEqual({ count: 3 }); }); @@ -308,7 +306,7 @@ describe('assign meta', () => { it('should provide the state in regular transitions (assigner)', () => { const { initialState } = machine; - const nextState = machine.transition(initialState, 'NEXT_FN'); + const nextState = machine.transition(initialState, { type: 'NEXT_FN' }); expect(nextState.context).toEqual({ count: 3 }); }); @@ -316,7 +314,9 @@ describe('assign meta', () => { it('should provide the assign action', () => { const { initialState } = machine; - const nextState = machine.transition(initialState, 'NEXT_ASSIGNER'); + const nextState = machine.transition(initialState, { + type: 'NEXT_ASSIGNER' + }); expect(nextState.context).toEqual({ count: 5 }); }); @@ -364,7 +364,7 @@ describe('assign meta', () => { }, on: { PING: { - actions: [sendParent('PONG')] + actions: [sendParent({ type: 'PONG' })] } } }); @@ -384,7 +384,7 @@ describe('assign meta', () => { }, on: { PING_CHILD: { - actions: [send('PING', { to: 'child' }), assignEventLog] + actions: [send({ type: 'PING' }, { to: 'child' }), assignEventLog] }, '*': { actions: [assignEventLog] @@ -400,8 +400,8 @@ describe('assign meta', () => { }) .start(); - service.send('PING_CHILD'); - service.send('PING_CHILD'); + service.send({ type: 'PING_CHILD' }); + service.send({ type: 'PING_CHILD' }); expect(state.context).toMatchInlineSnapshot(` Object { diff --git a/packages/core/test/deep.test.ts b/packages/core/test/deep.test.ts index 1fa351905d..b8379822d3 100644 --- a/packages/core/test/deep.test.ts +++ b/packages/core/test/deep.test.ts @@ -96,7 +96,7 @@ describe('deep transitions', () => { describe('exiting super/substates', () => { it('should exit all substates when superstates exits (A_EVENT)', () => { const actual = deepMachine - .transition(deepMachine.initialState, 'A_EVENT') + .transition(deepMachine.initialState, { type: 'A_EVENT' }) .actions.map((a) => a.type); const expected = ['EXIT_D', 'EXIT_C', 'EXIT_B', 'EXIT_A']; expect(actual).toEqual(expected); @@ -104,7 +104,7 @@ describe('deep transitions', () => { it('should exit substates and superstates when exiting (B_EVENT)', () => { const actual = deepMachine - .transition(deepMachine.initialState, 'B_EVENT') + .transition(deepMachine.initialState, { type: 'B_EVENT' }) .actions.map((a) => a.type); const expected = ['EXIT_D', 'EXIT_C', 'EXIT_B', 'EXIT_A']; expect(actual).toEqual(expected); @@ -112,7 +112,7 @@ describe('deep transitions', () => { it('should exit substates and superstates when exiting (C_EVENT)', () => { const actual = deepMachine - .transition(deepMachine.initialState, 'C_EVENT') + .transition(deepMachine.initialState, { type: 'C_EVENT' }) .actions.map((a) => a.type); const expected = ['EXIT_D', 'EXIT_C', 'EXIT_B', 'EXIT_A']; expect(actual).toEqual(expected); @@ -120,7 +120,7 @@ describe('deep transitions', () => { it('should exit superstates when exiting (D_EVENT)', () => { const actual = deepMachine - .transition(deepMachine.initialState, 'D_EVENT') + .transition(deepMachine.initialState, { type: 'D_EVENT' }) .actions.map((a) => a.type); const expected = ['EXIT_D', 'EXIT_C', 'EXIT_B', 'EXIT_A']; expect(actual).toEqual(expected); @@ -128,7 +128,7 @@ describe('deep transitions', () => { it('should exit substate when machine handles event (MACHINE_EVENT)', () => { const actual = deepMachine - .transition(deepMachine.initialState, 'MACHINE_EVENT') + .transition(deepMachine.initialState, { type: 'MACHINE_EVENT' }) .actions.map((a) => a.type); const expected = ['EXIT_D', 'EXIT_C', 'EXIT_B', 'EXIT_A']; expect(actual).toEqual(expected); @@ -147,7 +147,7 @@ describe('deep transitions', () => { it('should exit deep and enter deep (A_S)', () => { const actual = deepMachine - .transition(deepMachine.initialState, 'A_S') + .transition(deepMachine.initialState, { type: 'A_S' }) .actions.map((a) => a.type); const expected = DBCAPQRS; expect(actual).toEqual(expected); @@ -155,7 +155,7 @@ describe('deep transitions', () => { it('should exit deep and enter deep (D_P)', () => { const actual = deepMachine - .transition(deepMachine.initialState, 'D_P') + .transition(deepMachine.initialState, { type: 'D_P' }) .actions.map((a) => a.type); const expected = DBCAPQRS; expect(actual).toEqual(expected); @@ -163,7 +163,7 @@ describe('deep transitions', () => { it('should exit deep and enter deep (A_P)', () => { const actual = deepMachine - .transition(deepMachine.initialState, 'A_P') + .transition(deepMachine.initialState, { type: 'A_P' }) .actions.map((a) => a.type); const expected = DBCAPQRS; expect(actual).toEqual(expected); @@ -171,7 +171,7 @@ describe('deep transitions', () => { it('should exit deep and enter deep (D_S)', () => { const actual = deepMachine - .transition(deepMachine.initialState, 'D_S') + .transition(deepMachine.initialState, { type: 'D_S' }) .actions.map((a) => a.type); const expected = DBCAPQRS; expect(actual).toEqual(expected); diff --git a/packages/core/test/deterministic.test.ts b/packages/core/test/deterministic.test.ts index a4aaf89961..56d3934aca 100644 --- a/packages/core/test/deterministic.test.ts +++ b/packages/core/test/deterministic.test.ts @@ -94,7 +94,9 @@ describe('deterministic machine', () => { describe('machine.transition()', () => { it('should properly transition states based on string event', () => { - expect(lightMachine.transition('green', 'TIMER').value).toEqual('yellow'); + expect(lightMachine.transition('green', { type: 'TIMER' }).value).toEqual( + 'yellow' + ); }); it('should properly transition states based on event-like object', () => { @@ -106,8 +108,12 @@ describe('deterministic machine', () => { }); it('should not transition states for illegal transitions', () => { - expect(lightMachine.transition('green', 'FAKE').value).toEqual('green'); - expect(lightMachine.transition('green', 'FAKE').actions).toHaveLength(0); + expect(lightMachine.transition('green', { type: 'FAKE' }).value).toEqual( + 'green' + ); + expect( + lightMachine.transition('green', { type: 'FAKE' }).actions + ).toHaveLength(0); }); it('should throw an error if not given an event', () => { @@ -115,81 +121,95 @@ describe('deterministic machine', () => { }); it('should transition to nested states as target', () => { - expect(testMachine.transition('a', 'T').value).toEqual({ b: 'b1' }); + expect(testMachine.transition('a', { type: 'T' }).value).toEqual({ + b: 'b1' + }); }); it('should throw an error for transitions from invalid states', () => { - expect(() => testMachine.transition('fake', 'T')).toThrow(); + expect(() => testMachine.transition('fake', { type: 'T' })).toThrow(); }); it('should throw an error for transitions from invalid substates', () => { - expect(() => testMachine.transition('a.fake', 'T')).toThrow(); + expect(() => testMachine.transition('a.fake', { type: 'T' })).toThrow(); }); it('should use the machine.initialState when an undefined state is given', () => { - expect(lightMachine.transition(undefined, 'TIMER').value).toEqual( - 'yellow' - ); + expect( + lightMachine.transition(undefined, { type: 'TIMER' }).value + ).toEqual('yellow'); }); it('should use the machine.initialState when an undefined state is given (unhandled event)', () => { - expect(lightMachine.transition(undefined, 'TIMER').value).toEqual( - 'yellow' - ); + expect( + lightMachine.transition(undefined, { type: 'TIMER' }).value + ).toEqual('yellow'); }); }); describe('machine.transition() with nested states', () => { it('should properly transition a nested state', () => { expect( - lightMachine.transition({ red: 'walk' }, 'PED_COUNTDOWN').value + lightMachine.transition({ red: 'walk' }, { type: 'PED_COUNTDOWN' }) + .value ).toEqual({ red: 'wait' }); }); it('should transition from initial nested states', () => { - expect(lightMachine.transition('red', 'PED_COUNTDOWN').value).toEqual({ + expect( + lightMachine.transition('red', { type: 'PED_COUNTDOWN' }).value + ).toEqual({ red: 'wait' }); }); it('should transition from deep initial nested states', () => { - expect(lightMachine.transition('red', 'PED_COUNTDOWN').value).toEqual({ + expect( + lightMachine.transition('red', { type: 'PED_COUNTDOWN' }).value + ).toEqual({ red: 'wait' }); }); it('should bubble up events that nested states cannot handle', () => { - expect(lightMachine.transition({ red: 'stop' }, 'TIMER').value).toEqual( - 'green' - ); + expect( + lightMachine.transition({ red: 'stop' }, { type: 'TIMER' }).value + ).toEqual('green'); }); it('should not transition from illegal events', () => { - expect(lightMachine.transition({ red: 'walk' }, 'FAKE').value).toEqual({ + expect( + lightMachine.transition({ red: 'walk' }, { type: 'FAKE' }).value + ).toEqual({ red: 'walk' }); expect( - lightMachine.transition({ red: 'walk' }, 'FAKE').actions + lightMachine.transition({ red: 'walk' }, { type: 'FAKE' }).actions ).toHaveLength(0); - expect(deepMachine.transition('a1', 'FAKE').value).toEqual({ + expect(deepMachine.transition('a1', { type: 'FAKE' }).value).toEqual({ a1: { a2: { a3: 'a4' } } }); - expect(deepMachine.transition('a1', 'FAKE').actions).toHaveLength(0); + expect( + deepMachine.transition('a1', { type: 'FAKE' }).actions + ).toHaveLength(0); }); it('should transition to the deepest initial state', () => { - expect(lightMachine.transition('yellow', 'TIMER').value).toEqual({ + expect( + lightMachine.transition('yellow', { type: 'TIMER' }).value + ).toEqual({ red: 'walk' }); }); it('should return the equivalent state if no transition occurs', () => { - const initialState = lightMachine.transition( - lightMachine.initialState, - 'NOTHING' - ); - const nextState = lightMachine.transition(initialState, 'NOTHING'); + const initialState = lightMachine.transition(lightMachine.initialState, { + type: 'NOTHING' + }); + const nextState = lightMachine.transition(initialState, { + type: 'NOTHING' + }); expect(initialState.value).toEqual(nextState.value); expect(nextState.changed).toBe(false); @@ -207,7 +227,7 @@ describe('deterministic machine', () => { pass: {} } }); - expect(machine.transition('a', 'NEXT').value).toBe('pass'); + expect(machine.transition('a', { type: 'NEXT' }).value).toBe('pass'); }); }); @@ -227,15 +247,18 @@ describe('deterministic machine', () => { }); it('should work with substate nodes that have the same key', () => { - expect(machine.transition(machine.initialState, 'NEXT').value).toEqual( - 'test' - ); + expect( + machine.transition(machine.initialState, { type: 'NEXT' }).value + ).toEqual('test'); }); }); describe('forbidden events', () => { it('undefined transitions should forbid events', () => { - const walkState = lightMachine.transition({ red: 'walk' }, 'TIMER'); + const walkState = lightMachine.transition( + { red: 'walk' }, + { type: 'TIMER' } + ); expect(walkState.value).toEqual({ red: 'walk' }); }); diff --git a/packages/core/test/devTools.test.ts b/packages/core/test/devTools.test.ts index 915b45e57f..ab87427176 100644 --- a/packages/core/test/devTools.test.ts +++ b/packages/core/test/devTools.test.ts @@ -27,6 +27,6 @@ describe('devTools', () => { }); service.start(); - service.send('TOGGLE'); + service.send({ type: 'TOGGLE' }); }); }); diff --git a/packages/core/test/event.test.ts b/packages/core/test/event.test.ts index d1928d62cc..1ecb253f5c 100644 --- a/packages/core/test/event.test.ts +++ b/packages/core/test/event.test.ts @@ -9,7 +9,7 @@ describe('SCXML events', () => { initial: 'active', states: { active: { - entry: sendParent('EVENT') + entry: sendParent({ type: 'EVENT' }) } } }); @@ -87,9 +87,12 @@ describe('SCXML events', () => { waitingForCode: { on: { CODE: { - actions: respond('TOKEN', { - delay: 10 - }) + actions: respond( + { type: 'TOKEN' }, + { + delay: 10 + } + ) } } } @@ -108,9 +111,12 @@ describe('SCXML events', () => { id: 'auth-server', src: authServerMachine }, - entry: send('CODE', { - to: 'auth-server' - }), + entry: send( + { type: 'CODE' }, + { + to: 'auth-server' + } + ), on: { TOKEN: 'authorized' } @@ -125,7 +131,7 @@ describe('SCXML events', () => { .onDone(() => done()) .start(); - service.send('AUTH'); + service.send({ type: 'AUTH' }); }); }); diff --git a/packages/core/test/eventDescriptors.test.ts b/packages/core/test/eventDescriptors.test.ts index 253e9395d6..597f47d093 100644 --- a/packages/core/test/eventDescriptors.test.ts +++ b/packages/core/test/eventDescriptors.test.ts @@ -17,7 +17,7 @@ describe('event descriptors', () => { }); const service = interpret(machine).start(); - service.send('BAR'); + service.send({ type: 'BAR' }); expect(service.getSnapshot().value).toBe('C'); }); @@ -37,7 +37,7 @@ describe('event descriptors', () => { }); const service = interpret(machine).start(); - service.send('NEXT'); + service.send({ type: 'NEXT' }); expect(service.getSnapshot().value).toBe('pass'); }); @@ -57,7 +57,7 @@ describe('event descriptors', () => { }); const service = interpret(machine).start(); - service.send('NEXT'); + service.send({ type: 'NEXT' }); expect(service.getSnapshot().value).toBe('pass'); }); @@ -77,10 +77,10 @@ describe('event descriptors', () => { }); expect( - machine.transition(undefined, 'event').matches('success') + machine.transition(undefined, { type: 'event' }).matches('success') ).toBeFalsy(); expect( - machine.transition(undefined, 'eventually').matches('success') + machine.transition(undefined, { type: 'eventually' }).matches('success') ).toBeFalsy(); }); @@ -100,10 +100,10 @@ describe('event descriptors', () => { }); expect( - machine.transition(undefined, 'event').matches('success') + machine.transition(undefined, { type: 'event' }).matches('success') ).toBeTruthy(); expect( - machine.transition(undefined, 'eventually').matches('success') + machine.transition(undefined, { type: 'eventually' }).matches('success') ).toBeFalsy(); }); @@ -123,13 +123,17 @@ describe('event descriptors', () => { }); expect( - machine.transition(undefined, 'event.whatever').matches('success') + machine + .transition(undefined, { type: 'event.whatever' }) + .matches('success') ).toBeTruthy(); expect( - machine.transition(undefined, 'eventually').matches('success') + machine.transition(undefined, { type: 'eventually' }).matches('success') ).toBeFalsy(); expect( - machine.transition(undefined, 'eventually.event').matches('success') + machine + .transition(undefined, { type: 'eventually.event' }) + .matches('success') ).toBeFalsy(); }); @@ -149,7 +153,9 @@ describe('event descriptors', () => { }); expect( - machine.transition(undefined, 'event.first.second').matches('success') + machine + .transition(undefined, { type: 'event.first.second' }) + .matches('success') ).toBeTruthy(); }); @@ -170,7 +176,7 @@ describe('event descriptors', () => { expect( machine - .transition(undefined, 'event.foo.bar.first.second') + .transition(undefined, { type: 'event.foo.bar.first.second' }) .matches('success') ).toBeTruthy(); }); @@ -206,15 +212,21 @@ describe('event descriptors', () => { }); expect( - nonSCXMLMachine.transition(undefined, 'event.whatever').matches('start') + nonSCXMLMachine + .transition(undefined, { type: 'event.whatever' }) + .matches('start') ).toBeTruthy(); expect( - SCXMLMachine.transition(undefined, 'event.whatever').matches('success') + SCXMLMachine.transition(undefined, { type: 'event.whatever' }).matches( + 'success' + ) ).toBeTruthy(); expect( - SCXMLMachine.transition(undefined, 'eventually').matches('start') + SCXMLMachine.transition(undefined, { type: 'eventually' }).matches( + 'start' + ) ).toBeTruthy(); }); @@ -236,11 +248,13 @@ describe('event descriptors', () => { expect( machine - .transition(undefined, 'event.foo.bar.first.second') + .transition(undefined, { type: 'event.foo.bar.first.second' }) .matches('success') ).toBeFalsy(); expect( - machine.transition(undefined, 'whatever.event').matches('success') + machine + .transition(undefined, { type: 'whatever.event' }) + .matches('success') ).toBeFalsy(); }); @@ -261,10 +275,14 @@ describe('event descriptors', () => { }); expect( - machine.transition(undefined, 'eventually.bar.baz').matches('success') + machine + .transition(undefined, { type: 'eventually.bar.baz' }) + .matches('success') ).toBeFalsy(); expect( - machine.transition(undefined, 'prevent.whatever').matches('success') + machine + .transition(undefined, { type: 'prevent.whatever' }) + .matches('success') ).toBeFalsy(); }); }); diff --git a/packages/core/test/examples/6.8.test.ts b/packages/core/test/examples/6.8.test.ts index 65b4fdef22..72abbdbfd9 100644 --- a/packages/core/test/examples/6.8.test.ts +++ b/packages/core/test/examples/6.8.test.ts @@ -68,9 +68,9 @@ describe('Example 6.8', () => { testAll(machine, expected); it('should respect the history mechanism', () => { - const stateC = machine.transition({ A: 'B' }, '1'); - const stateF = machine.transition(stateC, '6'); - const stateActual = machine.transition(stateF, '5'); + const stateC = machine.transition({ A: 'B' }, { type: '1' }); + const stateF = machine.transition(stateC, { type: '6' }); + const stateActual = machine.transition(stateF, { type: '5' }); expect(stateActual.value).toEqual({ A: 'C' }); }); diff --git a/packages/core/test/final.test.ts b/packages/core/test/final.test.ts index 6ef5067b77..1b199f189e 100644 --- a/packages/core/test/final.test.ts +++ b/packages/core/test/final.test.ts @@ -67,21 +67,21 @@ const finalMachine = createMachine({ describe('final states', () => { it('should emit the "done.state.final.red" event when all nested states are in their final states', () => { - const redState = finalMachine.transition('yellow', 'TIMER'); + const redState = finalMachine.transition('yellow', { type: 'TIMER' }); expect(redState.value).toEqual({ red: { crosswalk1: 'walk', crosswalk2: 'walk' } }); - const waitState = finalMachine.transition(redState, 'PED_WAIT'); + const waitState = finalMachine.transition(redState, { type: 'PED_WAIT' }); expect(waitState.value).toEqual({ red: { crosswalk1: 'wait', crosswalk2: 'wait' } }); - const stopState = finalMachine.transition(waitState, 'PED_STOP'); + const stopState = finalMachine.transition(waitState, { type: 'PED_STOP' }); expect(stopState.value).toEqual({ red: { crosswalk1: 'stop', @@ -93,14 +93,14 @@ describe('final states', () => { expect.objectContaining({ type: 'stopCrosswalk1' }) ]); - const stopState2 = finalMachine.transition(stopState, 'PED_STOP'); + const stopState2 = finalMachine.transition(stopState, { type: 'PED_STOP' }); expect(stopState2.actions).toEqual([ expect.objectContaining({ type: 'stopCrosswalk2' }), expect.objectContaining({ type: 'prepareGreenLight' }) ]); - const greenState = finalMachine.transition(stopState, 'TIMER'); + const greenState = finalMachine.transition(stopState, { type: 'TIMER' }); expect(greenState.actions).toHaveLength(0); }); @@ -192,7 +192,7 @@ describe('final states', () => { }) .start(); - service.send('REQUEST_SECRET'); + service.send({ type: 'REQUEST_SECRET' }); }); it("should only call data expression once when entering root's final state", () => { diff --git a/packages/core/test/guards.test.ts b/packages/core/test/guards.test.ts index 65784818da..df2faac682 100644 --- a/packages/core/test/guards.test.ts +++ b/packages/core/test/guards.test.ts @@ -77,7 +77,7 @@ describe('guard conditions', () => { }, lightMachine ), - 'TIMER' + { type: 'TIMER', elapsed: 0 } ).value ).toEqual('green'); @@ -90,7 +90,7 @@ describe('guard conditions', () => { }, lightMachine ), - 'TIMER' + { type: 'TIMER', elapsed: 0 } ).value ).toEqual('yellow'); }); @@ -123,7 +123,7 @@ describe('guard conditions', () => { lightMachine ) ), - 'TIMER' + { type: 'TIMER', elapsed: 10 } ); expect(nextState.value).toEqual('green'); expect(nextState.actions).toEqual([]); @@ -140,7 +140,7 @@ describe('guard conditions', () => { lightMachine ) ), - 'TIMER' + { type: 'TIMER', elapsed: 10 } ); expect(nextState.value).toEqual('red'); }); @@ -156,7 +156,7 @@ describe('guard conditions', () => { lightMachine ) ), - 'TIMER_COND_OBJ' + { type: 'TIMER_COND_OBJ' } ); expect(nextState.value).toEqual('red'); }); @@ -172,13 +172,15 @@ describe('guard conditions', () => { lightMachine ) ), - 'TIMER' + { type: 'TIMER', elapsed: 10 } ); expect(nextState.value).toEqual('yellow'); }); it('should throw if string transition is not defined', () => { - expect(() => lightMachine.transition('red', 'BAD_COND')).toThrow(); + expect(() => + lightMachine.transition('red', { type: 'BAD_COND' }) + ).toThrow(); }); }); @@ -257,21 +259,27 @@ describe('guard conditions', () => { }); it('should guard against transition', () => { - expect(machine.transition({ A: 'A2', B: 'B0' }, 'T1').value).toEqual({ + expect( + machine.transition({ A: 'A2', B: 'B0' }, { type: 'T1' }).value + ).toEqual({ A: 'A2', B: 'B0' }); }); it('should allow a matching transition', () => { - expect(machine.transition({ A: 'A2', B: 'B0' }, 'T2').value).toEqual({ + expect( + machine.transition({ A: 'A2', B: 'B0' }, { type: 'T2' }).value + ).toEqual({ A: 'A2', B: 'B2' }); }); it('should check guards with interim states', () => { - expect(machine.transition({ A: 'A2', B: 'B0' }, 'A').value).toEqual({ + expect( + machine.transition({ A: 'A2', B: 'B0' }, { type: 'A' }).value + ).toEqual({ A: 'A5', B: 'B4' }); @@ -287,7 +295,7 @@ describe('guard conditions', () => { } }, b: { - entry: actions.raise('MICRO'), + entry: actions.raise({ type: 'MICRO' }), tags: 'theTag', on: { MICRO: { @@ -302,7 +310,7 @@ describe('guard conditions', () => { }); const service = interpret(machine).start(); - service.send('MACRO'); + service.send({ type: 'MACRO' }); expect(service.getSnapshot().value).toBe('c'); }); @@ -441,7 +449,7 @@ describe('referencing guards', () => { }); expect(() => { - machine.transition(machine.initialState, 'EVENT'); + machine.transition(machine.initialState, { type: 'EVENT' }); }).toThrow(); }); }); @@ -462,7 +470,7 @@ describe('guards - other', () => { }); const service = interpret(machine).start(); - service.send('EVENT'); + service.send({ type: 'EVENT' }); expect(service.getSnapshot().value).toBe('c'); }); @@ -513,7 +521,7 @@ describe('guards with child guards', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); }); @@ -535,7 +543,7 @@ describe('not() guard', () => { } }); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -563,7 +571,7 @@ describe('not() guard', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -593,7 +601,7 @@ describe('not() guard', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -622,7 +630,7 @@ describe('not() guard', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -645,7 +653,7 @@ describe('and() guard', () => { } }); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -673,7 +681,7 @@ describe('and() guard', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -706,7 +714,7 @@ describe('and() guard', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -739,7 +747,7 @@ describe('and() guard', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -762,7 +770,7 @@ describe('or() guard', () => { } }); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -791,7 +799,7 @@ describe('or() guard', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -824,7 +832,7 @@ describe('or() guard', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); @@ -857,7 +865,7 @@ describe('or() guard', () => { } ); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.matches('b')).toBeTruthy(); }); diff --git a/packages/core/test/history.test.ts b/packages/core/test/history.test.ts index d9e8a7ca7f..2f1ac478d3 100644 --- a/packages/core/test/history.test.ts +++ b/packages/core/test/history.test.ts @@ -34,33 +34,43 @@ describe('history states', () => { }); it('should go to the most recently visited state', () => { - const onSecondState = historyMachine.transition('on', 'SWITCH'); - const offState = historyMachine.transition(onSecondState, 'POWER'); + const onSecondState = historyMachine.transition('on', { type: 'SWITCH' }); + const offState = historyMachine.transition(onSecondState, { + type: 'POWER' + }); - expect(historyMachine.transition(offState, 'POWER').value).toEqual({ + expect( + historyMachine.transition(offState, { type: 'POWER' }).value + ).toEqual({ on: 'second' }); }); it('should go to the most recently visited state (explicit)', () => { - const onSecondState = historyMachine.transition('on', 'SWITCH'); - const offState = historyMachine.transition(onSecondState, 'H_POWER'); + const onSecondState = historyMachine.transition('on', { type: 'SWITCH' }); + const offState = historyMachine.transition(onSecondState, { + type: 'H_POWER' + }); - expect(historyMachine.transition(offState, 'H_POWER').value).toEqual({ + expect( + historyMachine.transition(offState, { type: 'H_POWER' }).value + ).toEqual({ on: 'second' }); }); it('should go to the initial state when no history present', () => { - expect(historyMachine.transition('off', 'POWER').value).toEqual({ + expect(historyMachine.transition('off', { type: 'POWER' }).value).toEqual({ on: 'first' }); }); it('should go to the initial state when no history present (explicit)', () => { - expect(historyMachine.transition('off', 'H_POWER').value).toEqual({ - on: 'first' - }); + expect(historyMachine.transition('off', { type: 'H_POWER' }).value).toEqual( + { + on: 'first' + } + ); }); it('should go to the most recently visited state by a transient transition', () => { @@ -103,11 +113,11 @@ describe('history states', () => { const service = interpret(machine).start(); - service.send('DEPLOY'); - service.send('SUCCESS'); - service.send('DESTROY'); - service.send('DEPLOY'); - service.send('FAILURE'); + service.send({ type: 'DEPLOY' }); + service.send({ type: 'SUCCESS' }); + service.send({ type: 'DESTROY' }); + service.send({ type: 'DEPLOY' }); + service.send({ type: 'FAILURE' }); expect(service.getSnapshot().value).toEqual({ idle: 'absent' }); }); @@ -201,41 +211,56 @@ describe('deep history states', () => { describe('history', () => { it('should go to the shallow history', () => { // on.first -> on.second.A - const state2A = historyMachine.transition({ on: 'first' }, 'SWITCH'); + const state2A = historyMachine.transition( + { on: 'first' }, + { type: 'SWITCH' } + ); // on.second.A -> on.second.B.P - const state2BP = historyMachine.transition(state2A, 'INNER'); + const state2BP = historyMachine.transition(state2A, { type: 'INNER' }); // on.second.B.P -> off - const stateOff = historyMachine.transition(state2BP, 'POWER'); - expect(historyMachine.transition(stateOff, 'POWER').value).toEqual({ + const stateOff = historyMachine.transition(state2BP, { type: 'POWER' }); + expect( + historyMachine.transition(stateOff, { type: 'POWER' }).value + ).toEqual({ on: { second: 'A' } }); }); it('should go to the deep history (explicit)', () => { // on.first -> on.second.A - const state2A = historyMachine.transition({ on: 'first' }, 'SWITCH'); + const state2A = historyMachine.transition( + { on: 'first' }, + { type: 'SWITCH' } + ); // on.second.A -> on.second.B.P - const state2BP = historyMachine.transition(state2A, 'INNER'); + const state2BP = historyMachine.transition(state2A, { type: 'INNER' }); // on.second.B.P -> off - const stateOff = historyMachine.transition(state2BP, 'POWER'); - expect(historyMachine.transition(stateOff, 'DEEP_POWER').value).toEqual({ + const stateOff = historyMachine.transition(state2BP, { type: 'POWER' }); + expect( + historyMachine.transition(stateOff, { type: 'DEEP_POWER' }).value + ).toEqual({ on: { second: { B: 'P' } } }); }); it('should go to the deepest history', () => { // on.first -> on.second.A - const state2A = historyMachine.transition({ on: 'first' }, 'SWITCH'); + const state2A = historyMachine.transition( + { on: 'first' }, + { type: 'SWITCH' } + ); // on.second.A -> on.second.B.P - const state2BP = historyMachine.transition(state2A, 'INNER'); + const state2BP = historyMachine.transition(state2A, { type: 'INNER' }); // on.second.B.P -> on.second.B.Q - const state2BQ = historyMachine.transition(state2BP, 'INNER'); + const state2BQ = historyMachine.transition(state2BP, { type: 'INNER' }); // on.second.B.Q -> off - const stateOff = historyMachine.transition(state2BQ, 'POWER'); - expect(historyMachine.transition(stateOff, 'DEEP_POWER').value).toEqual({ + const stateOff = historyMachine.transition(state2BQ, { type: 'POWER' }); + expect( + historyMachine.transition(stateOff, { type: 'DEEP_POWER' }).value + ).toEqual({ on: { second: { B: 'Q' } } }); }); @@ -322,71 +347,93 @@ describe('parallel history states', () => { it('should ignore parallel state history', () => { // on.first -> on.second.A - const stateABKL = historyMachine.transition( - historyMachine.initialState, - 'SWITCH' - ); + const stateABKL = historyMachine.transition(historyMachine.initialState, { + type: 'SWITCH' + }); // INNER_A twice - const stateACDKL = historyMachine.transition(stateABKL, 'INNER_A'); + const stateACDKL = historyMachine.transition(stateABKL, { + type: 'INNER_A' + }); - const stateOff = historyMachine.transition(stateACDKL, 'POWER'); - expect(historyMachine.transition(stateOff, 'POWER').value).toEqual({ + const stateOff = historyMachine.transition(stateACDKL, { type: 'POWER' }); + expect( + historyMachine.transition(stateOff, { type: 'POWER' }).value + ).toEqual({ on: { A: 'B', K: 'L' } }); }); it('should remember first level state history', () => { // on.first -> on.second.A - const stateABKL = historyMachine.transition( - historyMachine.initialState, - 'SWITCH' - ); + const stateABKL = historyMachine.transition(historyMachine.initialState, { + type: 'SWITCH' + }); // INNER_A twice - const stateACDKL = historyMachine.transition(stateABKL, 'INNER_A'); + const stateACDKL = historyMachine.transition(stateABKL, { + type: 'INNER_A' + }); - const stateOff = historyMachine.transition(stateACDKL, 'POWER'); - expect(historyMachine.transition(stateOff, 'DEEP_POWER').value).toEqual({ + const stateOff = historyMachine.transition(stateACDKL, { type: 'POWER' }); + expect( + historyMachine.transition(stateOff, { type: 'DEEP_POWER' }).value + ).toEqual({ on: { A: { C: 'D' }, K: 'L' } }); }); it('should re-enter each regions of parallel state correctly', () => { // on.first -> on.second.A - const stateABKL = historyMachine.transition( - historyMachine.initialState, - 'SWITCH' - ); + const stateABKL = historyMachine.transition(historyMachine.initialState, { + type: 'SWITCH' + }); // INNER_A twice - const stateACDKL = historyMachine.transition(stateABKL, 'INNER_A'); - const stateACEKL = historyMachine.transition(stateACDKL, 'INNER_A'); + const stateACDKL = historyMachine.transition(stateABKL, { + type: 'INNER_A' + }); + const stateACEKL = historyMachine.transition(stateACDKL, { + type: 'INNER_A' + }); // INNER_K twice - const stateACEKMN = historyMachine.transition(stateACEKL, 'INNER_K'); - const stateACEKMO = historyMachine.transition(stateACEKMN, 'INNER_K'); + const stateACEKMN = historyMachine.transition(stateACEKL, { + type: 'INNER_K' + }); + const stateACEKMO = historyMachine.transition(stateACEKMN, { + type: 'INNER_K' + }); - const stateOff = historyMachine.transition(stateACEKMO, 'POWER'); - expect(historyMachine.transition(stateOff, 'DEEP_POWER').value).toEqual({ + const stateOff = historyMachine.transition(stateACEKMO, { type: 'POWER' }); + expect( + historyMachine.transition(stateOff, { type: 'DEEP_POWER' }).value + ).toEqual({ on: { A: { C: 'E' }, K: { M: 'O' } } }); }); it('should re-enter multiple history states', () => { // on.first -> on.second.A - const stateABKL = historyMachine.transition( - historyMachine.initialState, - 'SWITCH' - ); + const stateABKL = historyMachine.transition(historyMachine.initialState, { + type: 'SWITCH' + }); // INNER_A twice - const stateACDKL = historyMachine.transition(stateABKL, 'INNER_A'); - const stateACEKL = historyMachine.transition(stateACDKL, 'INNER_A'); + const stateACDKL = historyMachine.transition(stateABKL, { + type: 'INNER_A' + }); + const stateACEKL = historyMachine.transition(stateACDKL, { + type: 'INNER_A' + }); // INNER_K twice - const stateACEKMN = historyMachine.transition(stateACEKL, 'INNER_K'); - const stateACEKMO = historyMachine.transition(stateACEKMN, 'INNER_K'); + const stateACEKMN = historyMachine.transition(stateACEKL, { + type: 'INNER_K' + }); + const stateACEKMO = historyMachine.transition(stateACEKMN, { + type: 'INNER_K' + }); - const stateOff = historyMachine.transition(stateACEKMO, 'POWER'); + const stateOff = historyMachine.transition(stateACEKMO, { type: 'POWER' }); expect( - historyMachine.transition(stateOff, 'PARALLEL_HISTORY').value + historyMachine.transition(stateOff, { type: 'PARALLEL_HISTORY' }).value ).toEqual({ on: { A: { C: 'D' }, K: { M: 'N' } } }); @@ -394,21 +441,29 @@ describe('parallel history states', () => { it('should re-enter a parallel with partial history', () => { // on.first -> on.second.A - const stateABKL = historyMachine.transition( - historyMachine.initialState, - 'SWITCH' - ); + const stateABKL = historyMachine.transition(historyMachine.initialState, { + type: 'SWITCH' + }); // INNER_A twice - const stateACDKL = historyMachine.transition(stateABKL, 'INNER_A'); - const stateACEKL = historyMachine.transition(stateACDKL, 'INNER_A'); + const stateACDKL = historyMachine.transition(stateABKL, { + type: 'INNER_A' + }); + const stateACEKL = historyMachine.transition(stateACDKL, { + type: 'INNER_A' + }); // INNER_K twice - const stateACEKMN = historyMachine.transition(stateACEKL, 'INNER_K'); - const stateACEKMO = historyMachine.transition(stateACEKMN, 'INNER_K'); + const stateACEKMN = historyMachine.transition(stateACEKL, { + type: 'INNER_K' + }); + const stateACEKMO = historyMachine.transition(stateACEKMN, { + type: 'INNER_K' + }); - const stateOff = historyMachine.transition(stateACEKMO, 'POWER'); + const stateOff = historyMachine.transition(stateACEKMO, { type: 'POWER' }); expect( - historyMachine.transition(stateOff, 'PARALLEL_SOME_HISTORY').value + historyMachine.transition(stateOff, { type: 'PARALLEL_SOME_HISTORY' }) + .value ).toEqual({ on: { A: { C: 'D' }, K: { M: 'N' } } }); @@ -416,21 +471,29 @@ describe('parallel history states', () => { it('should re-enter a parallel with full history', () => { // on.first -> on.second.A - const stateABKL = historyMachine.transition( - historyMachine.initialState, - 'SWITCH' - ); + const stateABKL = historyMachine.transition(historyMachine.initialState, { + type: 'SWITCH' + }); // INNER_A twice - const stateACDKL = historyMachine.transition(stateABKL, 'INNER_A'); - const stateACEKL = historyMachine.transition(stateACDKL, 'INNER_A'); + const stateACDKL = historyMachine.transition(stateABKL, { + type: 'INNER_A' + }); + const stateACEKL = historyMachine.transition(stateACDKL, { + type: 'INNER_A' + }); // INNER_K twice - const stateACEKMN = historyMachine.transition(stateACEKL, 'INNER_K'); - const stateACEKMO = historyMachine.transition(stateACEKMN, 'INNER_K'); + const stateACEKMN = historyMachine.transition(stateACEKL, { + type: 'INNER_K' + }); + const stateACEKMO = historyMachine.transition(stateACEKMN, { + type: 'INNER_K' + }); - const stateOff = historyMachine.transition(stateACEKMO, 'POWER'); + const stateOff = historyMachine.transition(stateACEKMO, { type: 'POWER' }); expect( - historyMachine.transition(stateOff, 'PARALLEL_DEEP_HISTORY').value + historyMachine.transition(stateOff, { type: 'PARALLEL_DEEP_HISTORY' }) + .value ).toEqual({ on: { A: { C: 'E' }, K: { M: 'O' } } }); @@ -453,7 +516,7 @@ describe('transient history', () => { }); it('should have history on transient transitions', () => { - const nextState = transientMachine.transition('A', 'EVENT'); + const nextState = transientMachine.transition('A', { type: 'EVENT' }); expect(nextState.value).toEqual('C'); }); }); @@ -487,8 +550,8 @@ it('internal transition to a history state should enter default history state co }) ).start(); - service.send('NEXT'); - service.send('NEXT'); + service.send({ type: 'NEXT' }); + service.send({ type: 'NEXT' }); expect(service.getSnapshot().value).toEqual({ second: 'nested' @@ -526,15 +589,19 @@ describe('multistage history states', () => { }); it('should go to the most recently visited state', () => { - const onTurboState = pcWithTurboButtonMachine.transition( - 'running', - 'SWITCH_TURBO' - ); - const offState = pcWithTurboButtonMachine.transition(onTurboState, 'POWER'); - const loadingState = pcWithTurboButtonMachine.transition(offState, 'POWER'); + const onTurboState = pcWithTurboButtonMachine.transition('running', { + type: 'SWITCH_TURBO' + }); + const offState = pcWithTurboButtonMachine.transition(onTurboState, { + type: 'POWER' + }); + const loadingState = pcWithTurboButtonMachine.transition(offState, { + type: 'POWER' + }); expect( - pcWithTurboButtonMachine.transition(loadingState, 'STARTED').value + pcWithTurboButtonMachine.transition(loadingState, { type: 'STARTED' }) + .value ).toEqual({ running: 'turbo' }); }); }); diff --git a/packages/core/test/id.test.ts b/packages/core/test/id.test.ts index 4a97c4ee56..3e38896090 100644 --- a/packages/core/test/id.test.ts +++ b/packages/core/test/id.test.ts @@ -98,7 +98,7 @@ describe('State node IDs', () => { } }); - expect(brokenMachine.transition('foo', 'ACTION').value).toEqual({ + expect(brokenMachine.transition('foo', { type: 'ACTION' }).value).toEqual({ bar: { qux: 'quux' } }); }); diff --git a/packages/core/test/internalTransitions.test.ts b/packages/core/test/internalTransitions.test.ts index ac149e95a8..ae00640825 100644 --- a/packages/core/test/internalTransitions.test.ts +++ b/packages/core/test/internalTransitions.test.ts @@ -55,20 +55,18 @@ const topLevelMachine = createMachine({ describe('internal transitions', () => { it('parent state should enter child state without re-entering self', () => { - const nextState = wordMachine.transition( - wordMachine.initialState, - 'RIGHT_CLICK' - ); + const nextState = wordMachine.transition(wordMachine.initialState, { + type: 'RIGHT_CLICK' + }); expect(nextState.value).toEqual({ direction: 'right' }); expect(nextState.actions.length).toBe(0); }); it('parent state should re-enter self upon transitioning to child state if internal is false', () => { - const nextState = wordMachine.transition( - wordMachine.initialState, - 'RIGHT_CLICK_EXTERNAL' - ); + const nextState = wordMachine.transition(wordMachine.initialState, { + type: 'RIGHT_CLICK_EXTERNAL' + }); expect(nextState.value).toEqual({ direction: 'right' }); expect(nextState.actions.length).toBe(2); @@ -79,7 +77,9 @@ describe('internal transitions', () => { }); it('parent state should only exit/reenter if there is an explicit self-transition', () => { - const resetState = wordMachine.transition('direction.center', 'RESET'); + const resetState = wordMachine.transition('direction.center', { + type: 'RESET' + }); expect(resetState.value).toEqual({ direction: 'left' }); expect(resetState.actions.map((a) => a.type)).toEqual([ @@ -89,10 +89,9 @@ describe('internal transitions', () => { }); it('parent state should only exit/reenter if there is an explicit self-transition (to child)', () => { - const resetState = wordMachine.transition( - 'direction.right', - 'RESET_TO_CENTER' - ); + const resetState = wordMachine.transition('direction.right', { + type: 'RESET_TO_CENTER' + }); expect(resetState.value).toEqual({ direction: 'center' }); expect(resetState.actions.map((a) => a.type)).toEqual([ @@ -102,40 +101,49 @@ describe('internal transitions', () => { }); it('should listen to events declared at top state', () => { - const actualState = topLevelMachine.transition('Failure', 'CLICKED_CLOSE'); + const actualState = topLevelMachine.transition('Failure', { + type: 'CLICKED_CLOSE' + }); expect(actualState.value).toEqual('Hidden'); }); it('should work with targetless transitions (in conditional array)', () => { - const sameState = topLevelMachine.transition('Hidden', 'TARGETLESS_ARRAY'); + const sameState = topLevelMachine.transition('Hidden', { + type: 'TARGETLESS_ARRAY' + }); expect(sameState.actions.map((a) => a.type)).toEqual(['doSomething']); }); it('should work with targetless transitions (in object)', () => { - const sameState = topLevelMachine.transition('Hidden', 'TARGETLESS_OBJECT'); + const sameState = topLevelMachine.transition('Hidden', { + type: 'TARGETLESS_OBJECT' + }); expect(sameState.actions.map((a) => a.type)).toEqual(['doSomething']); }); it('should work on parent with targetless transitions (in conditional array)', () => { - const sameState = topLevelMachine.transition('Failure', 'TARGETLESS_ARRAY'); + const sameState = topLevelMachine.transition('Failure', { + type: 'TARGETLESS_ARRAY' + }); expect(sameState.actions.map((a) => a.type)).toEqual(['doSomethingParent']); }); it('should work with targetless transitions (in object)', () => { - const sameState = topLevelMachine.transition( - 'Failure', - 'TARGETLESS_OBJECT' - ); + const sameState = topLevelMachine.transition('Failure', { + type: 'TARGETLESS_OBJECT' + }); expect(sameState.actions.map((a) => a.type)).toEqual(['doSomethingParent']); }); it('should maintain the child state when targetless transition is handled by parent', () => { - const hiddenState = topLevelMachine.transition('Hidden', 'PARENT_EVENT'); + const hiddenState = topLevelMachine.transition('Hidden', { + type: 'PARENT_EVENT' + }); expect(hiddenState.value).toEqual('Hidden'); }); @@ -184,7 +192,7 @@ describe('internal transitions', () => { const service = interpret(machine).start(); - service.send('REENTER'); + service.send({ type: 'REENTER' }); expect(service.getSnapshot().context).toEqual({ sourceStateEntries: 1, @@ -235,7 +243,7 @@ describe('internal transitions', () => { const service = interpret(machine).start(); - service.send('REENTER'); + service.send({ type: 'REENTER' }); expect(service.getSnapshot().context).toEqual({ sourceStateExits: 0, diff --git a/packages/core/test/interpreter.test.ts b/packages/core/test/interpreter.test.ts index f48033ef8f..bf63471919 100644 --- a/packages/core/test/interpreter.test.ts +++ b/packages/core/test/interpreter.test.ts @@ -25,7 +25,7 @@ const lightMachine = createMachine({ initial: 'green', states: { green: { - entry: [actions.send('TIMER', { delay: 10 })], + entry: [actions.send({ type: 'TIMER' }, { delay: 10 })], on: { TIMER: 'yellow', KEEP_GOING: { @@ -34,7 +34,7 @@ const lightMachine = createMachine({ } }, yellow: { - entry: [actions.send('TIMER', { delay: 10 })], + entry: [actions.send({ type: 'TIMER' }, { delay: 10 })], on: { TIMER: 'red' } @@ -151,7 +151,9 @@ describe('interpreter', () => { ); const currentState = 'green'; - const nextState = lightMachine.transition(currentState, 'TIMER'); + const nextState = lightMachine.transition(currentState, { + type: 'TIMER' + }); // saves state and recreate it const recreated = JSON.parse(JSON.stringify(nextState)); @@ -295,14 +297,19 @@ describe('interpreter', () => { } }, pending: { - entry: send('FINISH', { - delay: (ctx, e) => - ctx.initialDelay + - ('wait' in e - ? (e as Extract) - .wait - : 0) - }), + entry: send( + { type: 'FINISH' }, + { + delay: (ctx, e) => + ctx.initialDelay + + ('wait' in e + ? (e as Extract< + DelayExpMachineEvents, + { type: 'ACTIVATE' } + >).wait + : 0) + } + ), on: { FINISH: 'finished' } @@ -367,14 +374,17 @@ describe('interpreter', () => { } }, pending: { - entry: send('FINISH', { - delay: (ctx, _, { _event }) => - ctx.initialDelay + - (_event.data as Extract< - DelayExpMachineEvents, - { type: 'ACTIVATE' } - >).wait - }), + entry: send( + { type: 'FINISH' }, + { + delay: (ctx, _, { _event }) => + ctx.initialDelay + + (_event.data as Extract< + DelayExpMachineEvents, + { type: 'ACTIVATE' } + >).wait + } + ), on: { FINISH: 'finished' } @@ -540,7 +550,7 @@ describe('interpreter', () => { expect(activityState).toEqual('on'); - service.send('TURN_OFF'); + service.send({ type: 'TURN_OFF' }); expect(activityState).toEqual('off'); }); @@ -618,11 +628,10 @@ describe('interpreter', () => { } ); - const activeState = toggleMachine.transition( - toggleMachine.initialState, - 'TOGGLE' - ); - const bState = toggleMachine.transition(activeState, 'SWITCH'); + const activeState = toggleMachine.transition(toggleMachine.initialState, { + type: 'TOGGLE' + }); + const bState = toggleMachine.transition(activeState, { type: 'SWITCH' }); interpret(toggleMachine).start(bState); @@ -643,7 +652,7 @@ describe('interpreter', () => { service.start(); clock.increment(5); - service.send('KEEP_GOING'); + service.send({ type: 'KEEP_GOING' }); expect(currentState!.value).toEqual('green'); clock.increment(10); @@ -656,13 +665,19 @@ describe('interpreter', () => { states: { first: { entry: [ - send('FOO', { - id: 'foo', - delay: 100 - }), - send('BAR', { - delay: 200 - }), + send( + { type: 'FOO' }, + { + id: 'foo', + delay: 100 + } + ), + send( + { type: 'BAR' }, + { + delay: 200 + } + ), actions.cancel(() => 'foo') ], on: { @@ -693,11 +708,13 @@ describe('interpreter', () => { deferEvents: false }); - expect(() => service.send('SOME_EVENT')).toThrowError(/uninitialized/); + expect(() => service.send({ type: 'SOME_EVENT' })).toThrowError( + /uninitialized/ + ); service.start(); - expect(() => service.send('SOME_EVENT')).not.toThrow(); + expect(() => service.send({ type: 'SOME_EVENT' })).not.toThrow(); }); it('should not throw an error if an event is sent to an uninitialized interpreter if { deferEvents: true }', () => { @@ -706,11 +723,11 @@ describe('interpreter', () => { deferEvents: true }); - expect(() => service.send('SOME_EVENT')).not.toThrow(); + expect(() => service.send({ type: 'SOME_EVENT' })).not.toThrow(); service.start(); - expect(() => service.send('SOME_EVENT')).not.toThrow(); + expect(() => service.send({ type: 'SOME_EVENT' })).not.toThrow(); }); it('should not throw an error if an event is sent to an uninitialized interpreter (default options)', () => { @@ -718,11 +735,11 @@ describe('interpreter', () => { clock: new SimulatedClock() }); - expect(() => service.send('SOME_EVENT')).not.toThrow(); + expect(() => service.send({ type: 'SOME_EVENT' })).not.toThrow(); service.start(); - expect(() => service.send('SOME_EVENT')).not.toThrow(); + expect(() => service.send({ type: 'SOME_EVENT' })).not.toThrow(); }); it('should defer events sent to an uninitialized service', (done) => { @@ -750,8 +767,8 @@ describe('interpreter', () => { .onDone(() => done()); // uninitialized - deferService.send('NEXT_A'); - deferService.send('NEXT_B'); + deferService.send({ type: 'NEXT_A' }); + deferService.send({ type: 'NEXT_B' }); expect(state).not.toBeDefined(); @@ -792,12 +809,12 @@ describe('interpreter', () => { }).onTransition((s) => (state = s)); service.start(); - service.send('TIMER'); // yellow + service.send({ type: 'TIMER' }); // yellow expect(state.value).toEqual('yellow'); service.stop(); try { - service.send('TIMER'); // red if interpreter is not stopped + service.send({ type: 'TIMER' }); // red if interpreter is not stopped } catch (e) { expect(state.value).toEqual('yellow'); } @@ -828,8 +845,8 @@ describe('interpreter', () => { logger: (msg) => logs.push(msg) }).start(); - service.send('LOG'); - service.send('LOG'); + service.send({ type: 'LOG' }); + service.send({ type: 'LOG' }); expect(logs.length).toBe(2); expect(logs).toEqual([{ count: 1 }, { count: 2 }]); @@ -849,7 +866,7 @@ describe('interpreter', () => { }, on: { PING: { - actions: [actions.respond('PONG')] + actions: [actions.respond({ type: 'PONG' })] } } }); @@ -866,7 +883,7 @@ describe('interpreter', () => { }, on: { PING_CHILD: { - actions: [send('PING', { to: 'child' }), logAction] + actions: [send({ type: 'PING' }, { to: 'child' }), logAction] }, '*': { actions: [logAction] @@ -878,8 +895,8 @@ describe('interpreter', () => { logger: (msg) => logs.push(msg) }).start(); - service.send('PING_CHILD'); - service.send('PING_CHILD'); + service.send({ type: 'PING_CHILD' }); + service.send({ type: 'PING_CHILD' }); expect(logs.length).toBe(4); expect(logs).toMatchInlineSnapshot(` @@ -918,7 +935,7 @@ describe('interpreter', () => { foo: { on: { EXTERNAL_EVENT: { - actions: [raise('RAISED_EVENT'), logAction] + actions: [raise({ type: 'RAISED_EVENT' }), logAction] } } } @@ -934,7 +951,7 @@ describe('interpreter', () => { logger: (msg) => logs.push(msg) }).start(); - service.send('EXTERNAL_EVENT'); + service.send({ type: 'EXTERNAL_EVENT' }); expect(logs.length).toBe(2); expect(logs).toEqual(['EXTERNAL_EVENT', 'RAISED_EVENT']); @@ -981,7 +998,10 @@ describe('interpreter', () => { initial: 'foo', states: { foo: { - entry: [send('EVENT_2'), send('EVENT_1', { to: '#_internal' })], + entry: [ + send({ type: 'EVENT_2' }), + send({ type: 'EVENT_1' }, { to: '#_internal' }) + ], on: { EVENT_1: 'pass', EVENT_2: 'fail' @@ -1089,7 +1109,7 @@ describe('interpreter', () => { .onDone(() => done()) .start(); - service.send('ACTIVATE'); + service.send({ type: 'ACTIVATE' }); }); it('can send events with an object', (done) => { @@ -1137,8 +1157,8 @@ describe('interpreter', () => { }) .start(); - toggleService.send('ACTIVATE'); - toggleService.send('INACTIVATE'); + toggleService.send({ type: 'ACTIVATE' }); + toggleService.send({ type: 'INACTIVATE' }); }); }); @@ -1266,7 +1286,7 @@ describe('interpreter', () => { service.stop(); - service.send('TRIGGER'); + service.send({ type: 'TRIGGER' }); setTimeout(() => { expect(called).toBeFalsy(); @@ -1313,16 +1333,16 @@ describe('interpreter', () => { expect(stateCount).toEqual(1); - toggleService.send('TOGGLE'); + toggleService.send({ type: 'TOGGLE' }); expect(stateCount).toEqual(2); - toggleService.send('TOGGLE'); + toggleService.send({ type: 'TOGGLE' }); expect(stateCount).toEqual(3); sub.unsubscribe(); - toggleService.send('TOGGLE'); + toggleService.send({ type: 'TOGGLE' }); expect(stateCount).toEqual(3); }); @@ -1345,7 +1365,7 @@ describe('interpreter', () => { const service = interpret(stateMachine) .onTransition((current) => stateValues.push(current.value)) .start(); - service.send('START'); + service.send({ type: 'START' }); const expectedStateValues = ['idle', 'next']; expect(stateValues.length).toEqual(expectedStateValues.length); @@ -1382,7 +1402,7 @@ describe('interpreter', () => { const service = interpret(stateMachine) .onTransition((current) => stateValues.push(current.value)) .start(); - service.send('START'); + service.send({ type: 'START' }); const expectedStateValues = ['idle', 'next']; expect(stateValues.length).toEqual(expectedStateValues.length); @@ -1488,12 +1508,12 @@ describe('interpreter', () => { (state) => (count = state.context.count) ); - service.send('INC'); - service.send('INC'); + service.send({ type: 'INC' }); + service.send({ type: 'INC' }); subscription.unsubscribe(); - service.send('INC'); - service.send('INC'); - service.send('INC'); + service.send({ type: 'INC' }); + service.send({ type: 'INC' }); + service.send({ type: 'INC' }); }); it('should call complete() once a final state is reached', () => { @@ -1575,7 +1595,7 @@ describe('interpreter', () => { active: { on: { FIRE: { - actions: sendParent('FIRED') + actions: sendParent({ type: 'FIRED' }) } } } @@ -1806,7 +1826,7 @@ describe('interpreter', () => { expect(state.children).toHaveProperty('promiseChild'); expect(state.children).toHaveProperty('observableChild'); - service.send('NEXT'); + service.send({ type: 'NEXT' }); } }); }); diff --git a/packages/core/test/invalid.test.ts b/packages/core/test/invalid.test.ts index 391f661deb..af99e55ad9 100644 --- a/packages/core/test/invalid.test.ts +++ b/packages/core/test/invalid.test.ts @@ -22,28 +22,35 @@ const machine = createMachine({ describe('invalid or resolved states', () => { it('should resolve a String state', () => { - expect(machine.transition('A', 'E').value).toEqual({ A: 'A1', B: 'B1' }); + expect(machine.transition('A', { type: 'E' }).value).toEqual({ + A: 'A1', + B: 'B1' + }); }); it('should resolve transitions from empty states', () => { - expect(machine.transition({ A: {}, B: {} }, 'E').value).toEqual({ + expect(machine.transition({ A: {}, B: {} }, { type: 'E' }).value).toEqual({ A: 'A1', B: 'B1' }); }); it('should allow transitioning from valid states', () => { - machine.transition({ A: 'A1', B: 'B1' }, 'E'); + machine.transition({ A: 'A1', B: 'B1' }, { type: 'E' }); }); it('should reject transitioning from bad state configs', () => { - expect(() => machine.transition({ A: 'A3', B: 'B3' }, 'E')).toThrow(); + expect(() => + machine.transition({ A: 'A3', B: 'B3' }, { type: 'E' }) + ).toThrow(); }); it('should resolve transitioning from partially valid states', () => { - expect(machine.transition({ A: 'A1', B: {} }, 'E').value).toEqual({ - A: 'A1', - B: 'B1' - }); + expect(machine.transition({ A: 'A1', B: {} }, { type: 'E' }).value).toEqual( + { + A: 'A1', + B: 'B1' + } + ); }); }); diff --git a/packages/core/test/invoke.test.ts b/packages/core/test/invoke.test.ts index 54235f23d3..fbea138999 100644 --- a/packages/core/test/invoke.test.ts +++ b/packages/core/test/invoke.test.ts @@ -53,7 +53,7 @@ const fetchMachine = createMachine<{ userId: string | undefined }>({ data: { user: (_: any, e: any) => e.user } }, failure: { - entry: sendParent('REJECT') + entry: sendParent({ type: 'REJECT' }) } } }); @@ -106,7 +106,7 @@ describe('invoke', () => { initial: 'init', states: { init: { - entry: [sendParent('INC'), sendParent('INC')] + entry: [sendParent({ type: 'INC' }), sendParent({ type: 'INC' })] } } }); @@ -172,7 +172,11 @@ describe('invoke', () => { init: { on: { FORWARD_DEC: { - actions: [sendParent('DEC'), sendParent('DEC'), sendParent('DEC')] + actions: [ + sendParent({ type: 'DEC' }), + sendParent({ type: 'DEC' }), + sendParent({ type: 'DEC' }) + ] } } } @@ -227,7 +231,7 @@ describe('invoke', () => { }) .start(); - service.send('FORWARD_DEC'); + service.send({ type: 'FORWARD_DEC' }); }); it('should forward events to services if autoForward: true before processing them', (done) => { @@ -324,10 +328,10 @@ describe('invoke', () => { }) .start(); - service.send('START'); - service.send('INCREMENT'); - service.send('INCREMENT'); - service.send('INCREMENT'); + service.send({ type: 'START' }); + service.send({ type: 'INCREMENT' }); + service.send({ type: 'INCREMENT' }); + service.send({ type: 'INCREMENT' }); }); it('should start services (explicit machine, invoke = config)', (done) => { @@ -354,7 +358,7 @@ describe('invoke', () => { data: { user: (_: any, e: any) => e.user } }, failure: { - entry: sendParent('REJECT') + entry: sendParent({ type: 'REJECT' }) } } }); @@ -401,7 +405,7 @@ describe('invoke', () => { done(); }) .start() - .send('GO_TO_WAITING'); + .send({ type: 'GO_TO_WAITING' }); }); it('should start services (explicit machine, invoke = machine)', (done) => { @@ -410,7 +414,7 @@ describe('invoke', () => { done(); }) .start() - .send('GO_TO_WAITING_MACHINE'); + .send({ type: 'GO_TO_WAITING_MACHINE' }); }); it('should start services (machine as invoke config)', (done) => { @@ -543,7 +547,7 @@ describe('invoke', () => { initial: 'init', states: { init: { - entry: [sendParent('STOP')] + entry: [sendParent({ type: 'STOP' })] } } }) @@ -590,7 +594,7 @@ describe('invoke', () => { on: { NEXT: 'two' } }, two: { - entry: sendParent('NEXT') + entry: sendParent({ type: 'NEXT' }) } } }); @@ -605,7 +609,7 @@ describe('invoke', () => { }, states: { one: { - entry: send('NEXT', { to: 'foo-child' }), + entry: send({ type: 'NEXT' }, { to: 'foo-child' }), on: { NEXT: 'two' } }, two: { @@ -638,7 +642,7 @@ describe('invoke', () => { }, states: { one: { - entry: send('NEXT', { to: 'foo-child' }), + entry: send({ type: 'NEXT' }, { to: 'foo-child' }), on: { NEXT: 'two' } }, two: { @@ -664,7 +668,7 @@ describe('invoke', () => { id: 'foo-child', src: subMachine }, - entry: send('NEXT', { to: 'foo-child' }), + entry: send({ type: 'NEXT' }, { to: 'foo-child' }), on: { NEXT: 'two' } }, two: { @@ -704,7 +708,7 @@ describe('invoke', () => { src: doneSubMachine, onDone: 'two' }, - entry: send('NEXT', { to: 'foo-child' }) + entry: send({ type: 'NEXT' }, { to: 'foo-child' }) }, two: { on: { NEXT: 'three' } @@ -805,13 +809,13 @@ describe('invoke', () => { expect(invokeDisposeCount).toEqual(0); expect(actionsCount).toEqual(0); - service.send('UPDATE'); + service.send({ type: 'UPDATE' }); expect(entryActionsCount).toEqual(1); expect(invokeCount).toEqual(1); expect(invokeDisposeCount).toEqual(0); expect(actionsCount).toEqual(1); - service.send('UPDATE'); + service.send({ type: 'UPDATE' }); expect(entryActionsCount).toEqual(1); expect(invokeCount).toEqual(1); expect(invokeDisposeCount).toEqual(0); @@ -888,7 +892,7 @@ describe('invoke', () => { }) .start(); - service.send('START'); + service.send({ type: 'START' }); }); }); @@ -1445,7 +1449,7 @@ describe('invoke', () => { interpret(callbackMachine) .onTransition((current) => stateValues.push(current.value)) .start() - .send('BEGIN'); + .send({ type: 'BEGIN' }); for (let i = 0; i < expectedStateValues.length; i++) { expect(stateValues[i]).toEqual(expectedStateValues[i]); } @@ -1487,7 +1491,7 @@ describe('invoke', () => { interpret(callbackMachine) .onTransition((current) => stateValues.push(current.value)) .start() - .send('BEGIN'); + .send({ type: 'BEGIN' }); for (let i = 0; i < expectedStateValues.length; i++) { expect(stateValues[i]).toEqual(expectedStateValues[i]); } @@ -1538,7 +1542,7 @@ describe('invoke', () => { stateValues.push(current.value); }) .start() - .send('BEGIN'); + .send({ type: 'BEGIN' }); for (let i = 0; i < expectedStateValues.length; i++) { expect(stateValues[i]).toEqual(expectedStateValues[i]); @@ -1626,7 +1630,7 @@ describe('invoke', () => { }); }) }, - entry: send('PING', { to: 'child' }), + entry: send({ type: 'PING' }, { to: 'child' }), on: { PONG: 'done' } @@ -1812,7 +1816,7 @@ describe('invoke', () => { } }); - interpret(errorMachine).start().send('FETCH'); + interpret(errorMachine).start().send({ type: 'FETCH' }); expect(errorHandlersCalled).toEqual(1); }); @@ -1820,7 +1824,7 @@ describe('invoke', () => { it('should be able to be stringified', () => { const waitingState = fetcherMachine.transition( fetcherMachine.initialState, - 'GO_TO_WAITING' + { type: 'GO_TO_WAITING' } ); expect(() => { @@ -1878,7 +1882,7 @@ describe('invoke', () => { }, on: { STOPCHILD: { - actions: send('STOP', { to: 'invoked.child' }) + actions: send({ type: 'STOP' }, { to: 'invoked.child' }) } } }, @@ -1907,7 +1911,7 @@ describe('invoke', () => { }) .start(); - service.send('STOPCHILD'); + service.send({ type: 'STOPCHILD' }); }); }); }); @@ -2224,8 +2228,8 @@ describe('invoke', () => { }) .start(); - countService.send('INC'); - countService.send('INC'); + countService.send({ type: 'INC' }); + countService.send({ type: 'INC' }); }); it('behaviors should have reference to the parent', (done) => { @@ -2246,7 +2250,7 @@ describe('invoke', () => { initial: 'waiting', states: { waiting: { - entry: send('PING', { to: 'ponger' }), + entry: send({ type: 'PING' }, { to: 'ponger' }), invoke: { id: 'ponger', src: pongBehavior @@ -2302,8 +2306,8 @@ describe('invoke', () => { }) .start(); - countService.send('INC'); - countService.send('INC'); + countService.send({ type: 'INC' }); + countService.send({ type: 'INC' }); }); it('should schedule events in a FIFO queue', (done) => { @@ -2345,7 +2349,7 @@ describe('invoke', () => { }) .start(); - countService.send('INC'); + countService.send({ type: 'INC' }); }); }); @@ -2358,7 +2362,7 @@ describe('invoke', () => { on: { PING: { // Sends 'PONG' event to parent machine - actions: sendParent('PONG') + actions: sendParent({ type: 'PONG' }) } } } @@ -2379,7 +2383,7 @@ describe('invoke', () => { src: pongMachine }, // Sends 'PING' event to child machine with ID 'pong' - entry: send('PING', { to: 'pong' }), + entry: send({ type: 'PING' }, { to: 'pong' }), on: { PONG: 'innerSuccess' } @@ -2621,7 +2625,7 @@ describe('invoke', () => { }, on: { NEXT: { - actions: raise('STOP_ONE') + actions: raise({ type: 'STOP_ONE' }) } } } @@ -2656,7 +2660,7 @@ describe('invoke', () => { .onDone(() => done()) .start(); - service.send('NEXT'); + service.send({ type: 'NEXT' }); }); it('should invoke an actor when reentering invoking state within a single macrostep', () => { @@ -3106,7 +3110,7 @@ describe('invoke', () => { }); const service = interpret(machine).start(); - service.send('FINISH'); + service.send({ type: 'FINISH' }); expect(disposed).toBe(true); }); @@ -3140,7 +3144,7 @@ describe('invoke', () => { }); const service = interpret(machine).start(); - service.send('FINISH'); + service.send({ type: 'FINISH' }); expect(disposed).toBe(true); }); }); diff --git a/packages/core/test/machine.test.ts b/packages/core/test/machine.test.ts index 944d1b33a1..ffa028a128 100644 --- a/packages/core/test/machine.test.ts +++ b/packages/core/test/machine.test.ts @@ -156,7 +156,9 @@ describe('machine', () => { `"new entry"` ); - expect(differentMachine.transition('foo', 'EVENT').value).toEqual('bar'); + expect( + differentMachine.transition('foo', { type: 'EVENT' }).value + ).toEqual('bar'); }); it('should not override context if not defined', () => { @@ -390,7 +392,7 @@ describe('machine', () => { } }); - const barState = machine.transition(undefined, 'NEXT'); + const barState = machine.transition(undefined, { type: 'NEXT' }); const jsonBarState = JSON.parse(JSON.stringify(barState)); @@ -410,7 +412,7 @@ describe('machine', () => { } }); - const nextState = machine.transition(undefined, 'NEXT'); + const nextState = machine.transition(undefined, { type: 'NEXT' }); const persistedState = JSON.stringify(nextState); @@ -486,7 +488,7 @@ describe('machine', () => { expect(state.value).toEqual({}); - const nextState = testMachine.transition(state, 'INC'); + const nextState = testMachine.transition(state, { type: 'INC' }); expect(nextState.context.value).toEqual(43); }); diff --git a/packages/core/test/meta.test.ts b/packages/core/test/meta.test.ts index dbb267c1fe..cb03648c97 100644 --- a/packages/core/test/meta.test.ts +++ b/packages/core/test/meta.test.ts @@ -73,7 +73,7 @@ describe('state meta data', () => { }); it('states should aggregate meta data', () => { - const yellowState = lightMachine.transition('green', 'TIMER'); + const yellowState = lightMachine.transition('green', { type: 'TIMER' }); expect(yellowState.meta).toEqual({ 'light.yellow': { yellowData: 'yellow data' @@ -84,7 +84,7 @@ describe('state meta data', () => { }); it('states should aggregate meta data (deep)', () => { - expect(lightMachine.transition('yellow', 'TIMER').meta).toEqual({ + expect(lightMachine.transition('yellow', { type: 'TIMER' }).meta).toEqual({ 'light.red': { redData: { nested: { @@ -149,7 +149,7 @@ describe('transition meta data', () => { } }); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.transitions.map((t) => t.meta)).toMatchInlineSnapshot(` Array [ diff --git a/packages/core/test/microstep.test.ts b/packages/core/test/microstep.test.ts index b9e6e7d801..29bda8adea 100644 --- a/packages/core/test/microstep.test.ts +++ b/packages/core/test/microstep.test.ts @@ -12,7 +12,7 @@ describe('machine.microstep()', () => { } }, a: { - entry: raise('NEXT'), + entry: raise({ type: 'NEXT' }), on: { NEXT: 'b' } @@ -21,7 +21,7 @@ describe('machine.microstep()', () => { always: 'c' }, c: { - entry: raise('NEXT'), + entry: raise({ type: 'NEXT' }), on: { NEXT: 'd' } @@ -53,7 +53,7 @@ describe('machine.microstep()', () => { const states = machine.microstep( machine.resolveStateValue('first'), - 'TRIGGER', + { type: 'TRIGGER' }, undefined ); @@ -68,7 +68,7 @@ describe('machine.microstep()', () => { on: { TRIGGER: { target: 'second', - actions: raise('RAISED') + actions: raise({ type: 'RAISED' }) } } }, @@ -83,7 +83,7 @@ describe('machine.microstep()', () => { const states = machine.microstep( machine.resolveStateValue('first'), - 'TRIGGER', + { type: 'TRIGGER' }, undefined ); @@ -103,7 +103,7 @@ describe('machine.microstep()', () => { } }); - const states = machine.microstep(machine.initialState, 'TRIGGER'); + const states = machine.microstep(machine.initialState, { type: 'TRIGGER' }); expect(states.map((s) => s.value)).toEqual(['second']); }); @@ -116,7 +116,7 @@ describe('machine.microstep()', () => { on: { TRIGGER: { target: 'second', - actions: [raise('FOO'), raise('BAR')] + actions: [raise({ type: 'FOO' }), raise({ type: 'BAR' })] } } }, @@ -141,7 +141,7 @@ describe('machine.microstep()', () => { } }); - const states = machine.microstep(machine.initialState, 'TRIGGER'); + const states = machine.microstep(machine.initialState, { type: 'TRIGGER' }); expect(states.map((s) => [s.value, s._internalQueue.length])).toEqual([ ['second', 2], // foo, bar @@ -174,7 +174,7 @@ describe('machine.microstep()', () => { } }); - const states = machine.microstep(machine.initialState, 'TRIGGER'); + const states = machine.microstep(machine.initialState, { type: 'TRIGGER' }); expect(states.map((s) => s.actions.map((a) => a.type))).toEqual([ ['one'], diff --git a/packages/core/test/multiple.test.ts b/packages/core/test/multiple.test.ts index 1ab64cec1a..384b260e57 100644 --- a/packages/core/test/multiple.test.ts +++ b/packages/core/test/multiple.test.ts @@ -137,8 +137,8 @@ describe('multiple', () => { describe('transitions to parallel states', () => { const stateSimple = machine.initialState; - const stateInitial = machine.transition(stateSimple, 'INITIAL'); - const stateM = machine.transition(stateSimple, 'DEEP_M'); + const stateInitial = machine.transition(stateSimple, { type: 'INITIAL' }); + const stateM = machine.transition(stateSimple, { type: 'DEEP_M' }); it('should enter initial states of parallel states', () => { expect(stateInitial.value).toEqual({ @@ -151,48 +151,48 @@ describe('multiple', () => { }); it('should enter specific states in all regions', () => { - const stateCMR = machine.transition(stateSimple, 'DEEP_CMR'); + const stateCMR = machine.transition(stateSimple, { type: 'DEEP_CMR' }); expect(stateCMR.value).toEqual({ para: { A: 'C', K: 'M', P: 'R' } }); }); it('should enter specific states in some regions', () => { - const stateMR = machine.transition(stateSimple, 'DEEP_MR'); + const stateMR = machine.transition(stateSimple, { type: 'DEEP_MR' }); expect(stateMR.value).toEqual({ para: { A: 'B', K: 'M', P: 'R' } }); }); it.skip('should reject two targets in the same region', () => { expect(() => - machine.transition(stateSimple, 'BROKEN_SAME_REGION') + machine.transition(stateSimple, { type: 'BROKEN_SAME_REGION' }) ).toThrow(); }); it.skip('should reject targets inside and outside a region', () => { expect(() => - machine.transition(stateSimple, 'BROKEN_DIFFERENT_REGIONS') + machine.transition(stateSimple, { type: 'BROKEN_DIFFERENT_REGIONS' }) ).toThrow(); }); it.skip('should reject two targets in different regions', () => { expect(() => - machine.transition(stateSimple, 'BROKEN_DIFFERENT_REGIONS_2') + machine.transition(stateSimple, { type: 'BROKEN_DIFFERENT_REGIONS_2' }) ).toThrow(); }); it.skip('should reject two targets in different regions at different levels', () => { expect(() => - machine.transition(stateSimple, 'BROKEN_DIFFERENT_REGIONS_3') + machine.transition(stateSimple, { type: 'BROKEN_DIFFERENT_REGIONS_3' }) ).toThrow(); }); it.skip('should reject two deep targets in different regions at top level', () => { expect(() => - machine.transition(stateSimple, 'BROKEN_DIFFERENT_REGIONS_3') + machine.transition(stateSimple, { type: 'BROKEN_DIFFERENT_REGIONS_3' }) ).toThrow(); }); it.skip('should reject two deep targets in different regions at different levels', () => { expect(() => - machine.transition(stateSimple, 'BROKEN_DIFFERENT_REGIONS_4') + machine.transition(stateSimple, { type: 'BROKEN_DIFFERENT_REGIONS_4' }) ).toThrow(); }); }); diff --git a/packages/core/test/parallel.test.ts b/packages/core/test/parallel.test.ts index 9ad7a87259..8490ff3452 100644 --- a/packages/core/test/parallel.test.ts +++ b/packages/core/test/parallel.test.ts @@ -313,21 +313,21 @@ const raisingParallelMachine = createMachine({ initial: 'C', states: { A: { - entry: [raise('TURN_OFF')], + entry: [raise({ type: 'TURN_OFF' })], on: { EVENT_OUTER1_B: 'B', EVENT_OUTER1_C: 'C' } }, B: { - entry: [raise('TURN_ON')], + entry: [raise({ type: 'TURN_ON' })], on: { EVENT_OUTER1_A: 'A', EVENT_OUTER1_C: 'C' } }, C: { - entry: [raise('CLEAR')], + entry: [raise({ type: 'CLEAR' })], on: { EVENT_OUTER1_A: 'A', EVENT_OUTER1_B: 'B' @@ -562,13 +562,17 @@ describe('parallel states', () => { }); it('should have all parallel states represented in the state value', () => { - const nextState = wakMachine.transition(wakMachine.initialState, 'WAK1'); + const nextState = wakMachine.transition(wakMachine.initialState, { + type: 'WAK1' + }); expect(nextState.value).toEqual({ wak1: 'wak1sonB', wak2: 'wak2sonA' }); }); it('should have all parallel states represented in the state value (2)', () => { - const nextState = wakMachine.transition(wakMachine.initialState, 'WAK2'); + const nextState = wakMachine.transition(wakMachine.initialState, { + type: 'WAK2' + }); expect(nextState.value).toEqual({ wak1: 'wak1sonA', wak2: 'wak2sonB' }); }); @@ -584,7 +588,7 @@ describe('parallel states', () => { it('should work with regions without states', () => { const nextState = flatParallelMachine.transition( flatParallelMachine.initialState, - 'E' + { type: 'E' } ); expect(nextState.value).toEqual({ foo: {}, @@ -594,10 +598,9 @@ describe('parallel states', () => { }); it('should properly transition to relative substate', () => { - const nextState = composerMachine.transition( - composerMachine.initialState, - 'singleClickActivity' - ); + const nextState = composerMachine.transition(composerMachine.initialState, { + type: 'singleClickActivity' + }); expect(nextState.value).toEqual({ ReadOnly: { @@ -622,7 +625,7 @@ describe('parallel states', () => { it('should properly transition when raising events for a parallel state', () => { const nextState = raisingParallelMachine.transition( raisingParallelMachine.initialState, - 'EVENT_OUTER1_B' + { type: 'EVENT_OUTER1_B' } ); expect(nextState.value).toEqual({ @@ -675,7 +678,7 @@ describe('parallel states', () => { const savedState = simultaneousMachine.transition( simultaneousMachine.initialState, - 'SAVE' + { type: 'SAVE' } ); const unsavedState = simultaneousMachine.transition(savedState, { type: 'CHANGE', @@ -694,20 +697,17 @@ describe('parallel states', () => { describe('transitions with nested parallel states', () => { const initialState = nestedParallelState.initialState; - const simpleNextState = nestedParallelState.transition( - initialState, - 'EVENT_SIMPLE' - ); - const complexNextState = nestedParallelState.transition( - initialState, - 'EVENT_COMPLEX' - ); + const simpleNextState = nestedParallelState.transition(initialState, { + type: 'EVENT_SIMPLE' + }); + const complexNextState = nestedParallelState.transition(initialState, { + type: 'EVENT_COMPLEX' + }); it('should properly transition when in a simple nested state', () => { - const nextState = nestedParallelState.transition( - simpleNextState, - 'EVENT_STATE_NTJ0_WORK' - ); + const nextState = nestedParallelState.transition(simpleNextState, { + type: 'EVENT_STATE_NTJ0_WORK' + }); expect(nextState.value).toEqual({ OUTER1: { @@ -721,10 +721,9 @@ describe('parallel states', () => { }); it('should properly transition when in a complex nested state', () => { - const nextState = nestedParallelState.transition( - complexNextState, - 'EVENT_STATE_NTJ0_WORK' - ); + const nextState = nestedParallelState.transition(complexNextState, { + type: 'EVENT_STATE_NTJ0_WORK' + }); expect(nextState.value).toEqual({ OUTER1: { @@ -767,7 +766,7 @@ describe('parallel states', () => { }); it('should represent the flat nested parallel states in the state value', () => { - const result = machine.transition(machine.initialState, 'to-B'); + const result = machine.transition(machine.initialState, { type: 'to-B' }); expect(result.value).toEqual({ B: { @@ -782,10 +781,10 @@ describe('parallel states', () => { it('should properly evaluate deep flat parallel states', () => { const state1 = deepFlatParallelMachine.transition( deepFlatParallelMachine.initialState, - 'a' + { type: 'a' } ); - const state2 = deepFlatParallelMachine.transition(state1, 'c'); - const state3 = deepFlatParallelMachine.transition(state2, 'b'); + const state2 = deepFlatParallelMachine.transition(state1, { type: 'c' }); + const state3 = deepFlatParallelMachine.transition(state2, { type: 'b' }); expect(state3.value).toEqual({ V: { B: { @@ -827,7 +826,7 @@ describe('parallel states', () => { }); expect(() => { - machine.transition(machine.initialState, 'UPDATE'); + machine.transition(machine.initialState, { type: 'UPDATE' }); }).not.toThrow(); }); }); @@ -882,15 +881,13 @@ describe('parallel states', () => { } }); - const openMenuState = testMachine.transition( - testMachine.initialState, - 'toggle' - ); + const openMenuState = testMachine.transition(testMachine.initialState, { + type: 'toggle' + }); - const dashboardState = testMachine.transition( - openMenuState, - 'go to dashboard' - ); + const dashboardState = testMachine.transition(openMenuState, { + type: 'go to dashboard' + }); expect( dashboardState.matches({ Menu: 'Opened', Pages: 'Dashboard' }) @@ -924,11 +921,10 @@ describe('parallel states', () => { } }); - const run1 = testMachine.transition( - testMachine.initialState, - 'GOTO_FOOBAZ' - ); - const run2 = testMachine.transition(run1, 'GOTO_FOOBAZ'); + const run1 = testMachine.transition(testMachine.initialState, { + type: 'GOTO_FOOBAZ' + }); + const run2 = testMachine.transition(run1, { type: 'GOTO_FOOBAZ' }); expect(run2.context.log.length).toBe(2); }); @@ -996,7 +992,7 @@ describe('parallel states', () => { }) .start(); - service.send('FINISH'); + service.send({ type: 'FINISH' }); }); it('should raise a "done.state.*" event when a pseudostate of a history type is directly on a parallel state', () => { diff --git a/packages/core/test/patterns.test.ts b/packages/core/test/patterns.test.ts index ed9767990e..bcc3d8e64e 100644 --- a/packages/core/test/patterns.test.ts +++ b/packages/core/test/patterns.test.ts @@ -20,15 +20,21 @@ describe('patterns', () => { ...sequence(seq) }); - expect(sequenceMachine.transition(seq[0], 'NEXT').value).toEqual(seq[1]); + expect( + sequenceMachine.transition(seq[0], { type: 'NEXT' }).value + ).toEqual(seq[1]); - expect(sequenceMachine.transition(seq[1], 'PREV').value).toEqual(seq[0]); + expect( + sequenceMachine.transition(seq[1], { type: 'PREV' }).value + ).toEqual(seq[0]); expect( - sequenceMachine.transition(seq[seq.length - 1], 'NEXT').value + sequenceMachine.transition(seq[seq.length - 1], { type: 'NEXT' }).value ).toEqual(seq[seq.length - 1]); - expect(sequenceMachine.transition(seq[0], 'PREV').value).toEqual(seq[0]); + expect( + sequenceMachine.transition(seq[0], { type: 'PREV' }).value + ).toEqual(seq[0]); }); it('should customize the next/prev events', () => { @@ -37,20 +43,26 @@ describe('patterns', () => { const sequenceMachine = createMachine({ id: 'sequence', ...sequence(seq, { - nextEvent: 'FORWARD', - prevEvent: 'BACK' + nextEvent: { type: 'FORWARD' }, + prevEvent: { type: 'BACK' } }) }); - expect(sequenceMachine.transition(seq[0], 'NEXT').value).toEqual(seq[0]); + expect( + sequenceMachine.transition(seq[0], { type: 'NEXT' }).value + ).toEqual(seq[0]); - expect(sequenceMachine.transition(seq[1], 'PREV').value).toEqual(seq[1]); + expect( + sequenceMachine.transition(seq[1], { type: 'PREV' }).value + ).toEqual(seq[1]); - expect(sequenceMachine.transition(seq[0], 'FORWARD').value).toEqual( - seq[1] - ); + expect( + sequenceMachine.transition(seq[0], { type: 'FORWARD' }).value + ).toEqual(seq[1]); - expect(sequenceMachine.transition(seq[1], 'BACK').value).toEqual(seq[0]); + expect( + sequenceMachine.transition(seq[1], { type: 'BACK' }).value + ).toEqual(seq[0]); }); it('should allow next/prev events to be undefined', () => { @@ -59,32 +71,34 @@ describe('patterns', () => { const sequenceMachine = createMachine({ id: 'sequence', ...sequence(seq, { - nextEvent: 'FORWARD', + nextEvent: { type: 'FORWARD' }, prevEvent: undefined }) }); - expect(sequenceMachine.transition(seq[0], 'FORWARD').value).toEqual( - seq[1] - ); + expect( + sequenceMachine.transition(seq[0], { type: 'FORWARD' }).value + ).toEqual(seq[1]); - expect(sequenceMachine.transition(seq[1], 'BACK').value).toEqual(seq[1]); + expect( + sequenceMachine.transition(seq[1], { type: 'BACK' }).value + ).toEqual(seq[1]); const backSequenceMachine = createMachine({ id: 'backSequence', ...sequence(seq, { nextEvent: undefined, - prevEvent: 'BACK' + prevEvent: { type: 'BACK' } }) }); - expect(backSequenceMachine.transition(seq[0], 'FORWARD').value).toEqual( - seq[0] - ); + expect( + backSequenceMachine.transition(seq[0], { type: 'FORWARD' }).value + ).toEqual(seq[0]); - expect(backSequenceMachine.transition(seq[1], 'BACK').value).toEqual( - seq[0] - ); + expect( + backSequenceMachine.transition(seq[1], { type: 'BACK' }).value + ).toEqual(seq[0]); }); }); }); diff --git a/packages/core/test/predictableExec.test.ts b/packages/core/test/predictableExec.test.ts index c7e8ee3c0c..7ed5cd02db 100644 --- a/packages/core/test/predictableExec.test.ts +++ b/packages/core/test/predictableExec.test.ts @@ -88,7 +88,7 @@ describe('predictableExec', () => { actions: (_ctx, ev) => (eventArg = ev) } }, - entry: raise('RAISED') + entry: raise({ type: 'RAISED' }) }, c: {} } @@ -121,7 +121,7 @@ describe('predictableExec', () => { }) } }, - entry: raise('RAISED') + entry: raise({ type: 'RAISED' }) }, c: {} } @@ -148,7 +148,7 @@ describe('predictableExec', () => { on: { RAISED: 'c' }, - entry: raise('RAISED') + entry: raise({ type: 'RAISED' }) }, c: { invoke: { diff --git a/packages/core/test/rehydration.test.ts b/packages/core/test/rehydration.test.ts index 316e40cdf9..f7f9f18d35 100644 --- a/packages/core/test/rehydration.test.ts +++ b/packages/core/test/rehydration.test.ts @@ -55,7 +55,7 @@ describe('rehydration', () => { const restoredState = JSON.parse(persistedState); const service = interpret(machine).start(restoredState); - expect(service.getSnapshot().can('FOO')).toBe(true); + expect(service.getSnapshot().can({ type: 'FOO' })).toBe(true); }); }); diff --git a/packages/core/test/schema.test.ts b/packages/core/test/schema.test.ts index beef293e45..a28e47bdc9 100644 --- a/packages/core/test/schema.test.ts +++ b/packages/core/test/schema.test.ts @@ -56,13 +56,13 @@ describe('schema', () => { noop(m.context.foo); noop(m.context.baz.one); - m.transition('active', 'BAR'); + m.transition('active', { type: 'BAR' }); // @ts-expect-error noop(m.context.something); // @ts-expect-error - m.transition('active', 'INVALID'); + m.transition('active', { type: 'INVALID' }); }); it('schema should be present in the machine definition', () => { diff --git a/packages/core/test/scxml.test.ts b/packages/core/test/scxml.test.ts index 61bed333ac..6d43ecce97 100644 --- a/packages/core/test/scxml.test.ts +++ b/packages/core/test/scxml.test.ts @@ -412,7 +412,7 @@ async function runTestToCompletion( if (after) { (service.clock as SimulatedClock).increment(after); } - service.send(event.name); + service.send({ type: event.name }); const stateIds = getStateNodes(machine.root, nextState).map( (stateNode) => stateNode.id diff --git a/packages/core/test/state.test.ts b/packages/core/test/state.test.ts index 0199845a92..c74e7231cb 100644 --- a/packages/core/test/state.test.ts +++ b/packages/core/test/state.test.ts @@ -113,7 +113,7 @@ describe('State', () => { it('states from external transitions with entry actions should be changed', () => { const changedState = exampleMachine.transition( exampleMachine.initialState, - 'EXTERNAL' + { type: 'EXTERNAL' } ); expect(changedState.changed).toBe(true); }); @@ -121,16 +121,18 @@ describe('State', () => { it('states from internal transitions with no actions should be unchanged', () => { const changedState = exampleMachine.transition( exampleMachine.initialState, - 'EXTERNAL' + { type: 'EXTERNAL' } ); - const unchangedState = exampleMachine.transition(changedState, 'INERT'); + const unchangedState = exampleMachine.transition(changedState, { + type: 'INERT' + }); expect(unchangedState.changed).toBe(false); }); it('states from internal transitions with actions should be changed', () => { const changedState = exampleMachine.transition( exampleMachine.initialState, - 'INTERNAL' + { type: 'INTERNAL' } ); expect(changedState.changed).toBe(true); }); @@ -138,29 +140,30 @@ describe('State', () => { it('normal state transitions should be changed (initial state)', () => { const changedState = exampleMachine.transition( exampleMachine.initialState, - 'TO_TWO' + { type: 'TO_TWO', foo: 'test' } ); expect(changedState.changed).toBe(true); }); it('normal state transitions should be changed', () => { - const twoState = exampleMachine.transition( - exampleMachine.initialState, - 'TO_TWO' - ); - const changedState = exampleMachine.transition(twoState, 'FOO_EVENT'); + const twoState = exampleMachine.transition(exampleMachine.initialState, { + type: 'TO_TWO', + foo: 'test' + }); + const changedState = exampleMachine.transition(twoState, { + type: 'FOO_EVENT' + }); expect(changedState.changed).toBe(true); }); it('normal state transitions with unknown event should be unchanged', () => { - const twoState = exampleMachine.transition( - exampleMachine.initialState, - 'TO_TWO' - ); - const changedState = exampleMachine.transition( - twoState, - 'UNKNOWN_EVENT' as any - ); + const twoState = exampleMachine.transition(exampleMachine.initialState, { + type: 'TO_TWO', + foo: 'test' + }); + const changedState = exampleMachine.transition(twoState, { + type: 'UNKNOWN_EVENT' + } as any); expect(changedState.changed).toBe(false); }); @@ -181,7 +184,7 @@ describe('State', () => { } }); - const twoState = finalMachine.transition('one', 'DONE'); + const twoState = finalMachine.transition('one', { type: 'DONE' }); expect(twoState.changed).toBe(true); }); @@ -205,7 +208,9 @@ describe('State', () => { }); const { initialState } = assignMachine; - const changedState = assignMachine.transition(initialState, 'EVENT'); + const changedState = assignMachine.transition(initialState, { + type: 'EVENT' + }); expect(changedState.changed).toBe(true); expect(initialState.value).toEqual(changedState.value); }); @@ -290,23 +295,25 @@ describe('State', () => { expect( exampleMachine - .transition(exampleMachine.initialState, 'TO_TWO') + .transition(exampleMachine.initialState, { + type: 'TO_TWO', + foo: 'test' + }) .nextEvents.sort() ).toEqual(['DEEP_EVENT', 'FOO_EVENT', 'MACHINE_EVENT']); expect( exampleMachine - .transition(exampleMachine.initialState, 'TO_THREE') + .transition(exampleMachine.initialState, { type: 'TO_THREE' }) .nextEvents.sort() ).toEqual(['MACHINE_EVENT', 'P31', 'P32', 'THREE_EVENT']); }); it('returns events when transitioned from StateValue', () => { - const A = exampleMachine.transition( - exampleMachine.initialState, - 'TO_THREE' - ); - const B = exampleMachine.transition(A.value, 'TO_THREE'); + const A = exampleMachine.transition(exampleMachine.initialState, { + type: 'TO_THREE' + }); + const B = exampleMachine.transition(A.value, { type: 'TO_THREE' }); expect(B.nextEvents.sort()).toEqual([ 'MACHINE_EVENT', @@ -339,7 +346,10 @@ describe('State', () => { const stateFromConfig = exampleMachine.createState(jsonInitialState); expect( - exampleMachine.transition(stateFromConfig, 'TO_TWO').value + exampleMachine.transition(stateFromConfig, { + type: 'TO_TWO', + foo: 'test' + }).value ).toEqual({ two: { deep: 'foo' } }); @@ -362,9 +372,12 @@ describe('State', () => { it('the .event prop should be the event (string) that caused the transition', () => { const { initialState } = exampleMachine; - const nextState = exampleMachine.transition(initialState, 'TO_TWO'); + const nextState = exampleMachine.transition(initialState, { + type: 'TO_TWO', + foo: 'test' + }); - expect(nextState.event).toEqual({ type: 'TO_TWO' }); + expect(nextState.event).toEqual({ type: 'TO_TWO', foo: 'test' }); }); it('the .event prop should be the event (object) that caused the transition', () => { @@ -389,9 +402,14 @@ describe('State', () => { it('the ._event prop should be the SCXML event (string) that caused the transition', () => { const { initialState } = exampleMachine; - const nextState = exampleMachine.transition(initialState, 'TO_TWO'); + const nextState = exampleMachine.transition(initialState, { + type: 'TO_TWO', + foo: 'test' + }); - expect(nextState._event).toEqual(toSCXMLEvent('TO_TWO')); + expect(nextState._event).toEqual( + toSCXMLEvent({ type: 'TO_TWO', foo: 'test' }) + ); }); it('the ._event prop should be the SCXML event (object) that caused the transition', () => { @@ -477,7 +495,7 @@ describe('State', () => { }) .start(); - service.send('TOGGLE'); + service.send({ type: 'TOGGLE' }); }); it('_sessionid should persist through states (manual)', () => { @@ -499,7 +517,9 @@ describe('State', () => { initialState._sessionid = 'somesessionid'; - const nextState = testMachine.transition(initialState, 'TOGGLE'); + const nextState = testMachine.transition(initialState, { + type: 'TOGGLE' + }); expect(nextState._sessionid).toEqual('somesessionid'); }); @@ -515,13 +535,15 @@ describe('State', () => { it('should have transitions for the sent event', () => { expect( - exampleMachine.transition(initialState, 'TO_TWO').transitions + exampleMachine.transition(initialState, { type: 'TO_TWO', foo: 'test' }) + .transitions ).toContainEqual(expect.objectContaining({ eventType: 'TO_TWO' })); }); it('should have condition in the transition', () => { expect( - exampleMachine.transition(initialState, 'TO_TWO_MAYBE').transitions + exampleMachine.transition(initialState, { type: 'TO_TWO_MAYBE' }) + .transitions ).toContainEqual( expect.objectContaining({ eventType: 'TO_TWO_MAYBE', @@ -542,13 +564,19 @@ describe('State', () => { describe('State.prototype.toStrings', () => { it('should return all state paths as strings', () => { - const twoState = exampleMachine.transition('one', 'TO_TWO'); + const twoState = exampleMachine.transition('one', { + type: 'TO_TWO', + foo: 'test' + }); expect(twoState.toStrings()).toEqual(['two', 'two.deep', 'two.deep.foo']); }); it('should respect `delimiter` option for deeply nested states', () => { - const twoState = exampleMachine.transition('one', 'TO_TWO'); + const twoState = exampleMachine.transition('one', { + type: 'TO_TWO', + foo: 'test' + }); expect(twoState.toStrings(undefined, ':')).toEqual([ 'two', @@ -572,7 +600,7 @@ describe('State', () => { it('should show that a machine has reached its final state', () => { expect( - exampleMachine.transition(undefined, 'TO_FINAL').done + exampleMachine.transition(undefined, { type: 'TO_FINAL' }).done ).toBeTruthy(); }); }); @@ -591,7 +619,7 @@ describe('State', () => { } }); - expect(machine.initialState.can('NEXT')).toBe(true); + expect(machine.initialState.can({ type: 'NEXT' })).toBe(true); }); it('should return true for an event object that results in a transition to a different state', () => { @@ -812,7 +840,7 @@ describe('State', () => { }); const service = interpret(machine).start(); - service.getSnapshot().can('SPAWN'); + service.getSnapshot().can({ type: 'SPAWN' }); expect(spawned).toBe(false); }); @@ -833,7 +861,7 @@ describe('State', () => { const { initialState } = machine; - expect(initialState.can('EVENT')).toBeTruthy(); + expect(initialState.can({ type: 'EVENT' })).toBeTruthy(); expect(executed).toBeFalsy(); }); @@ -866,7 +894,7 @@ describe('State', () => { } }); - expect(machine.initialState.can('EVENT')).toBeTruthy(); + expect(machine.initialState.can({ type: 'EVENT' })).toBeTruthy(); }); it('should return true when transition targets a state that is already part of the current configuration but the final state value changes', () => { diff --git a/packages/core/test/stateIn.test.ts b/packages/core/test/stateIn.test.ts index 4418c668d7..922b2170f9 100644 --- a/packages/core/test/stateIn.test.ts +++ b/packages/core/test/stateIn.test.ts @@ -104,7 +104,7 @@ describe('transition "in" check', () => { } } }, - 'EVENT2' + { type: 'EVENT2' } ).value ).toEqual({ a: 'a2', @@ -129,7 +129,7 @@ describe('transition "in" check', () => { } } }, - 'EVENT3' + { type: 'EVENT3' } ).value ).toEqual({ a: 'a2', @@ -143,7 +143,9 @@ describe('transition "in" check', () => { }); it('should not transition if string state path does not match current state value', () => { - expect(machine.transition({ a: 'a1', b: 'b1' }, 'EVENT1').value).toEqual({ + expect( + machine.transition({ a: 'a1', b: 'b1' }, { type: 'EVENT1' }).value + ).toEqual({ a: 'a1', b: 'b1' }); @@ -161,7 +163,7 @@ describe('transition "in" check', () => { } } }, - 'EVENT2' + { type: 'EVENT2' } ).value ).toEqual({ a: 'a2', @@ -178,7 +180,7 @@ describe('transition "in" check', () => { expect( machine.transition( { a: 'a1', b: { b2: { foo: 'foo1', bar: 'bar1' } } }, - 'EVENT_DEEP' + { type: 'EVENT_DEEP' } ).value ).toEqual({ a: 'a1', @@ -195,7 +197,7 @@ describe('transition "in" check', () => { expect( machine.transition( { a: 'a1', b: { b2: { foo: 'foo1', bar: 'bar2' } } }, - 'EVENT_DEEP' + { type: 'EVENT_DEEP' } ).value ).toEqual({ a: 'a1', @@ -209,15 +211,24 @@ describe('transition "in" check', () => { }); it('should work to forbid events', () => { - const walkState = lightMachine.transition({ red: 'walk' }, 'TIMER'); + const walkState = lightMachine.transition( + { red: 'walk' }, + { type: 'TIMER' } + ); expect(walkState.value).toEqual({ red: 'walk' }); - const waitState = lightMachine.transition({ red: 'wait' }, 'TIMER'); + const waitState = lightMachine.transition( + { red: 'wait' }, + { type: 'TIMER' } + ); expect(waitState.value).toEqual({ red: 'wait' }); - const stopState = lightMachine.transition({ red: 'stop' }, 'TIMER'); + const stopState = lightMachine.transition( + { red: 'stop' }, + { type: 'TIMER' } + ); expect(stopState.value).toEqual('green'); }); diff --git a/packages/core/test/tags.test.ts b/packages/core/test/tags.test.ts index a19895e4fd..3611a4d0c2 100644 --- a/packages/core/test/tags.test.ts +++ b/packages/core/test/tags.test.ts @@ -21,7 +21,9 @@ describe('tags', () => { }); expect(machine.initialState.hasTag('go')).toBeTruthy(); - expect(machine.transition('yellow', 'TIMER').hasTag('go')).toBeFalsy(); + expect( + machine.transition('yellow', { type: 'TIMER' }).hasTag('go') + ).toBeFalsy(); }); it('supports tags in compound states', () => { @@ -87,7 +89,7 @@ describe('tags', () => { let state = machine.initialState; expect(state.tags).toEqual(new Set(['yes'])); - state = machine.transition(state, 'DEACTIVATE'); + state = machine.transition(state, { type: 'DEACTIVATE' }); expect(state.tags).toEqual(new Set(['yes', 'no'])); }); diff --git a/packages/core/test/transient.test.ts b/packages/core/test/transient.test.ts index 5e0bc213ac..d118d052e1 100644 --- a/packages/core/test/transient.test.ts +++ b/packages/core/test/transient.test.ts @@ -57,7 +57,7 @@ describe('transient states (eventless transitions)', () => { }, updateMachine ), - 'UPDATE_BUTTON_CLICKED' + { type: 'UPDATE_BUTTON_CLICKED' } ); expect(nextState.value).toEqual('D'); }); @@ -72,7 +72,7 @@ describe('transient states (eventless transitions)', () => { }, updateMachine ), - 'UPDATE_BUTTON_CLICKED' + { type: 'UPDATE_BUTTON_CLICKED' } ); expect(nextState.value).toEqual('B'); }); @@ -87,7 +87,7 @@ describe('transient states (eventless transitions)', () => { }, updateMachine ) as AnyState, - 'UPDATE_BUTTON_CLICKED' + { type: 'UPDATE_BUTTON_CLICKED' } ); expect(nextState.value).toEqual('C'); }); @@ -102,7 +102,7 @@ describe('transient states (eventless transitions)', () => { }, updateMachine ) as AnyState, - 'UPDATE_BUTTON_CLICKED' + { type: 'UPDATE_BUTTON_CLICKED' } ); expect(nextState.value).toEqual('F'); }); @@ -129,7 +129,7 @@ describe('transient states (eventless transitions)', () => { } }); - const state = machine.transition('A', 'TIMER'); + const state = machine.transition('A', { type: 'TIMER' }); expect(state.actions.map((a) => a.type)).toEqual([ 'exit_A', @@ -151,7 +151,7 @@ describe('transient states (eventless transitions)', () => { } }, A2: { - entry: raise('INT1') + entry: raise({ type: 'INT1' }) } } }, @@ -165,7 +165,7 @@ describe('transient states (eventless transitions)', () => { } }, B2: { - entry: raise('INT2') + entry: raise({ type: 'INT2' }) } } }, @@ -195,7 +195,7 @@ describe('transient states (eventless transitions)', () => { } }); - const state = machine.transition(machine.initialState, 'E'); + const state = machine.transition(machine.initialState, { type: 'E' }); expect(state.value).toEqual({ A: 'A2', B: 'B2', C: 'C4' }); }); @@ -251,7 +251,7 @@ describe('transient states (eventless transitions)', () => { } }); - const state = machine.transition(machine.initialState, 'E'); + const state = machine.transition(machine.initialState, { type: 'E' }); expect(state.value).toEqual({ A: 'A4', B: 'B4' }); }); @@ -307,7 +307,7 @@ describe('transient states (eventless transitions)', () => { } }); - const state = machine.transition(machine.initialState, 'E'); + const state = machine.transition(machine.initialState, { type: 'E' }); expect(state.value).toEqual({ A: 'A4', B: 'B4' }); }); @@ -355,7 +355,7 @@ describe('transient states (eventless transitions)', () => { }); let state = machine.initialState; // A1, B1, C1 - state = machine.transition(state, 'A'); // A2, B2, C2 + state = machine.transition(state, { type: 'A' }); // A2, B2, C2 expect(state.value).toEqual({ A: 'A2', B: 'B2', C: 'C2' }); }); @@ -402,7 +402,7 @@ describe('transient states (eventless transitions)', () => { }); let state = machine.initialState; // A1, B1, C1 - state = machine.transition(state, 'A'); // A2, B2, C2 + state = machine.transition(state, { type: 'A' }); // A2, B2, C2 expect(state.value).toEqual({ A: 'A2', B: 'B2', C: 'C2' }); }); @@ -413,15 +413,13 @@ describe('transient states (eventless transitions)', () => { it('should determine the resolved state from an initial transient state', () => { const morningState = greetingMachine.initialState; expect(morningState.value).toEqual('morning'); - const stillMorningState = greetingMachine.transition( - morningState, - 'CHANGE' - ); + const stillMorningState = greetingMachine.transition(morningState, { + type: 'CHANGE' + }); expect(stillMorningState.value).toEqual('morning'); - const eveningState = greetingMachine.transition( - stillMorningState, - 'RECHECK' - ); + const eveningState = greetingMachine.transition(stillMorningState, { + type: 'RECHECK' + }); expect(eveningState.value).toEqual('evening'); }); @@ -435,7 +433,7 @@ describe('transient states (eventless transitions)', () => { } }, b: { - entry: raise('BAR'), + entry: raise({ type: 'BAR' }), always: 'c', on: { BAR: 'd' @@ -451,7 +449,7 @@ describe('transient states (eventless transitions)', () => { } }); - const state = machine.transition('a', 'FOO'); + const state = machine.transition('a', { type: 'FOO' }); expect(state.value).toBe('e'); }); @@ -465,7 +463,7 @@ describe('transient states (eventless transitions)', () => { } }, b: { - entry: raise('BAR'), + entry: raise({ type: 'BAR' }), always: 'c', on: { BAR: 'd' @@ -481,7 +479,7 @@ describe('transient states (eventless transitions)', () => { } }); - const state = machine.transition('a', 'FOO'); + const state = machine.transition('a', { type: 'FOO' }); expect(state.value).toBe('e'); }); @@ -499,7 +497,7 @@ describe('transient states (eventless transitions)', () => { } }); - const state = machine.transition('a', 'FOO'); + const state = machine.transition('a', { type: 'FOO' }); expect(state.value).toBe('b'); }); @@ -519,7 +517,7 @@ describe('transient states (eventless transitions)', () => { } }); - const state = machine.transition('a', 'FOO'); + const state = machine.transition('a', { type: 'FOO' }); expect(state.value).toBe('pass'); }); @@ -539,7 +537,7 @@ describe('transient states (eventless transitions)', () => { } }); - const state = machine.transition('a', 'FOO'); + const state = machine.transition('a', { type: 'FOO' }); expect(state.value).toBe('pass'); }); @@ -576,7 +574,7 @@ describe('transient states (eventless transitions)', () => { service.start(); - service.send('ADD'); + service.send({ type: 'ADD' }); }); it('should work with transient transition on root (with `always`)', (done) => { @@ -613,7 +611,7 @@ describe('transient states (eventless transitions)', () => { service.start(); - service.send('ADD'); + service.send({ type: 'ADD' }); }); it("shouldn't crash when invoking a machine with initial transient transition depending on custom data", () => { @@ -742,7 +740,7 @@ describe('transient states (eventless transitions)', () => { } }); - const nextState = machine.transition(undefined, 'EVENT'); + const nextState = machine.transition(undefined, { type: 'EVENT' }); expect(nextState.done).toBeTruthy(); }); diff --git a/packages/core/test/types.test.ts b/packages/core/test/types.test.ts index baf63a3b9d..2462c9084d 100644 --- a/packages/core/test/types.test.ts +++ b/packages/core/test/types.test.ts @@ -311,7 +311,7 @@ describe('events', () => { type: 'FOO'; } }, - entry: raise('FOO') + entry: raise({ type: 'FOO' }) }); const service = interpret(machine).start(); diff --git a/packages/core/test/utils.ts b/packages/core/test/utils.ts index 81614706ff..df5821d531 100644 --- a/packages/core/test/utils.ts +++ b/packages/core/test/utils.ts @@ -14,7 +14,7 @@ export function testMultiTransition( if (typeof state === 'string' && state[0] === '{') { state = JSON.parse(state); } - const nextState = machine.transition(state, eventType); + const nextState = machine.transition(state, { type: eventType }); return nextState; }; diff --git a/packages/core/test/waitFor.test.ts b/packages/core/test/waitFor.test.ts index 759ffaa2a7..54e592e70e 100644 --- a/packages/core/test/waitFor.test.ts +++ b/packages/core/test/waitFor.test.ts @@ -16,7 +16,7 @@ describe('waitFor', () => { const service = interpret(machine).start(); - setTimeout(() => service.send('NEXT'), 10); + setTimeout(() => service.send({ type: 'NEXT' }), 10); const state = await waitFor(service, (s) => s.matches('b')); @@ -87,7 +87,7 @@ describe('waitFor', () => { const service = interpret(machine).start(); setTimeout(() => { - service.send('NEXT'); + service.send({ type: 'NEXT' }); }, 10); await expect( diff --git a/packages/xstate-analytics/test/analytics.test.ts b/packages/xstate-analytics/test/analytics.test.ts index 9ba33a308d..c91f6c7855 100644 --- a/packages/xstate-analytics/test/analytics.test.ts +++ b/packages/xstate-analytics/test/analytics.test.ts @@ -72,8 +72,8 @@ describe('@xstate/analytics', () => { service.start(); - service.send('TIMER'); - service.send('TIMER'); + service.send({ type: 'TIMER' }); + service.send({ type: 'TIMER' }); expect(analysis).toMatchInlineSnapshot(` Object { diff --git a/packages/xstate-fsm/README.md b/packages/xstate-fsm/README.md index 1bef95b975..f028213a4e 100644 --- a/packages/xstate-fsm/README.md +++ b/packages/xstate-fsm/README.md @@ -75,9 +75,11 @@ const toggleMachine = createMachine({ const { initialState } = toggleMachine; -const toggledState = toggleMachine.transition(initialState, 'TOGGLE'); +const toggledState = toggleMachine.transition(initialState, { type: 'TOGGLE' }); toggledState.value; -const untoggledState = toggleMachine.transition(toggledState, 'TOGGLE'); +const untoggledState = toggleMachine.transition(toggledState, { + type: 'TOGGLE' +}); untoggledState.value; // => 'inactive' ``` @@ -95,7 +97,7 @@ toggleService.subscribe((state) => { console.log(state.value); }); -toggleService.send('TOGGLE'); -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); +toggleService.send({ type: 'TOGGLE' }); toggleService.stop(); ``` diff --git a/packages/xstate-fsm/src/index.ts b/packages/xstate-fsm/src/index.ts index df0c554fd7..740c5400bb 100644 --- a/packages/xstate-fsm/src/index.ts +++ b/packages/xstate-fsm/src/index.ts @@ -56,12 +56,6 @@ function createMatcher(value: string) { return (stateValue) => value === stateValue; } -function toEventObject( - event: TEvent['type'] | TEvent -): TEvent { - return (typeof event === 'string' ? { type: event } : event) as TEvent; -} - function createUnchangedState< TC extends object, TE extends EventObject, @@ -149,14 +143,13 @@ export function createMachine< matches: createMatcher(fsmConfig.initial) }, transition: ( - state: string | StateMachine.State, - event: TEvent | TEvent['type'] + state: StateMachine.State, + event: TEvent ): StateMachine.State => { const { value, context } = typeof state === 'string' ? { value: state, context: fsmConfig.context! } : state; - const eventObject = toEventObject(event); const stateConfig = fsmConfig.states[value]; if (!IS_PRODUCTION && !stateConfig) { @@ -168,7 +161,7 @@ export function createMachine< if (stateConfig.on) { const transitions: Array< StateMachine.Transition - > = toArray(stateConfig.on[eventObject.type]); + > = toArray(stateConfig.on[event.type]); for (const transition of transitions) { if (transition === undefined) { @@ -197,7 +190,7 @@ export function createMachine< ); } - if (!guard || guard?.(context, eventObject)) { + if (!guard || guard?.(context, event)) { const allActions = (isTargetless ? toArray(actions) : ([] as any[]) @@ -210,7 +203,7 @@ export function createMachine< const [nonAssignActions, nextContext, assigned] = handleActions( allActions, context, - eventObject + event ); const resolvedTarget = target ?? value; @@ -256,12 +249,12 @@ export function interpret< const service = { _machine: machine, - send: (event: TEvent | TEvent['type']): void => { + send: (event: TEvent): void => { if (status !== InterpreterStatus.Running) { return; } state = machine.transition(state, event); - executeStateActions(state, toEventObject(event)); + executeStateActions(state, event); listeners.forEach((listener) => listener(state)); }, subscribe: (listener: StateMachine.StateListener) => { diff --git a/packages/xstate-fsm/src/types.ts b/packages/xstate-fsm/src/types.ts index bf3f7ea34a..ed89429f5a 100644 --- a/packages/xstate-fsm/src/types.ts +++ b/packages/xstate-fsm/src/types.ts @@ -150,7 +150,7 @@ export declare namespace StateMachine { initialState: State; transition: ( state: string | State, - event: TEvent['type'] | TEvent + event: TEvent ) => State; } @@ -161,7 +161,7 @@ export declare namespace StateMachine { TEvent extends EventObject, TState extends Typestate = { value: any; context: TContext } > { - send: (event: TEvent | TEvent['type']) => void; + send: (event: TEvent) => void; subscribe: ( listener: StateListener> ) => { diff --git a/packages/xstate-fsm/test/fsm.test.ts b/packages/xstate-fsm/test/fsm.test.ts index 9b697c73b4..c78cc8418a 100644 --- a/packages/xstate-fsm/test/fsm.test.ts +++ b/packages/xstate-fsm/test/fsm.test.ts @@ -114,7 +114,7 @@ describe('@xstate/fsm', () => { expect(initialState.actions).toEqual([{ type: 'foo' }]); }); it('should transition correctly', () => { - const nextState = lightFSM.transition('green', 'TIMER'); + const nextState = lightFSM.transition('green', { type: 'TIMER' }); expect(nextState.value).toEqual('yellow'); expect(nextState.actions.map((action) => action.type)).toEqual([ 'exitGreen', @@ -129,14 +129,14 @@ describe('@xstate/fsm', () => { }); it('should stay on the same state for undefined transitions', () => { - const nextState = lightFSM.transition('green', 'FAKE' as any); + const nextState = lightFSM.transition('green', { type: 'FAKE' } as any); expect(nextState.value).toBe('green'); expect(nextState.actions).toEqual([]); }); it('should throw an error for undefined states', () => { expect(() => { - lightFSM.transition('unknown', 'TIMER'); + lightFSM.transition('unknown', { type: 'TIMER' }); }).toThrow(); }); @@ -156,14 +156,17 @@ describe('@xstate/fsm', () => { }; const testMachine = createMachine(testConfig); expect(() => { - testMachine.transition('green', 'TARGET_INVALID'); + testMachine.transition('green', { type: 'TARGET_INVALID' }); }).toThrow( `State '${invalidState}' not found on machine ${testConfig.id ?? ''}` ); }); it('should work with guards', () => { - const yellowState = lightFSM.transition('yellow', 'EMERGENCY'); + const yellowState = lightFSM.transition('yellow', { + type: 'EMERGENCY', + value: 0 + }); expect(yellowState.value).toEqual('yellow'); const redState = lightFSM.transition('yellow', { @@ -173,7 +176,7 @@ describe('@xstate/fsm', () => { expect(redState.value).toEqual('red'); expect(redState.context.count).toBe(0); - const yellowOneState = lightFSM.transition('yellow', 'INC'); + const yellowOneState = lightFSM.transition('yellow', { type: 'INC' }); const redOneState = lightFSM.transition(yellowOneState, { type: 'EMERGENCY', value: 1 @@ -184,15 +187,17 @@ describe('@xstate/fsm', () => { }); it('should be changed if state changes', () => { - expect(lightFSM.transition('green', 'TIMER').changed).toBe(true); + expect(lightFSM.transition('green', { type: 'TIMER' }).changed).toBe(true); }); it('should be changed if any actions occur', () => { - expect(lightFSM.transition('yellow', 'INC').changed).toBe(true); + expect(lightFSM.transition('yellow', { type: 'INC' }).changed).toBe(true); }); it('should not be changed on unknown transitions', () => { - expect(lightFSM.transition('yellow', 'UNKNOWN' as any).changed).toBe(false); + expect( + lightFSM.transition('yellow', { type: 'UNKNOWN' } as any).changed + ).toBe(false); }); it('should match initialState', () => { @@ -207,7 +212,7 @@ describe('@xstate/fsm', () => { it('should match transition states', () => { const { initialState } = lightFSM; - const nextState = lightFSM.transition(initialState, 'TIMER'); + const nextState = lightFSM.transition(initialState, { type: 'TIMER' }); expect(nextState.matches('yellow')).toBeTruthy(); @@ -247,7 +252,7 @@ describe('interpreter', () => { } }); - toggleService.send('TOGGLE'); + toggleService.send({ type: 'TOGGLE' }); }); it('should execute actions', (done) => { @@ -278,7 +283,7 @@ describe('interpreter', () => { } }); - actionService.send('TOGGLE'); + actionService.send({ type: 'TOGGLE' }); }); it('should execute initial entry action', () => { @@ -362,7 +367,7 @@ describe('interpreter', () => { } }); - service.send('CHANGE'); + service.send({ type: 'CHANGE' }); }); it('should not re-execute exit/entry actions for transitions with undefined targets', () => { @@ -386,7 +391,7 @@ describe('interpreter', () => { expect(initialState.actions.map((a) => a.type)).toEqual(['entry']); - const nextState = machine.transition(initialState, 'EVENT'); + const nextState = machine.transition(initialState, { type: 'EVENT' }); expect(nextState.actions.map((a) => a.type)).toEqual(['action']); }); @@ -431,7 +436,7 @@ describe('interpreter', () => { const service = interpret(machine).start('bar'); expect(service.state.value).toBe('bar'); - service.send('NEXT'); + service.send({ type: 'NEXT' }); expect(service.state.matches('baz')).toBe(true); }); @@ -458,7 +463,7 @@ describe('interpreter', () => { expect(service.state.value).toBe('bar'); expect(service.state.context).toBe(context); - service.send('NEXT'); + service.send({ type: 'NEXT' }); expect(service.state.matches('baz')).toBe(true); }); diff --git a/packages/xstate-graph/src/graph.ts b/packages/xstate-graph/src/graph.ts index 484608de1f..08a7172b20 100644 --- a/packages/xstate-graph/src/graph.ts +++ b/packages/xstate-graph/src/graph.ts @@ -1,6 +1,5 @@ import { State, - Event, EventObject, AnyStateMachine, AnyState, @@ -29,16 +28,6 @@ function flatten(array: Array): T[] { return ([] as T[]).concat(...array); } -export function toEventObject( - event: Event -): TEvent { - if (typeof event === 'string' || typeof event === 'number') { - return ({ type: event } as unknown) as TEvent; - } - - return event; -} - /** * Returns all state nodes of the given `node`. * @param stateNode State node to recursively get child state nodes from @@ -145,7 +134,7 @@ export function getValueAdjacencyMap( return getNextEvents; }) - ).map((event) => toEventObject(event)); + ); for (const event of potentialEvents) { let nextState: TState; diff --git a/packages/xstate-immer/README.md b/packages/xstate-immer/README.md index 300c0d3c91..4eb8fe49d3 100644 --- a/packages/xstate-immer/README.md +++ b/packages/xstate-immer/README.md @@ -79,13 +79,13 @@ const toggleService = interpret(toggleMachine) }) .start(); -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // { count: 1, level: 0 } toggleService.send(levelUpdater.update(9)); // { count: 1, level: 9 } -toggleService.send('TOGGLE'); +toggleService.send({ type: 'TOGGLE' }); // { count: 2, level: 9 } toggleService.send(levelUpdater.update(-100)); diff --git a/packages/xstate-immer/test/immer.test.ts b/packages/xstate-immer/test/immer.test.ts index 0aacd1255b..6278168691 100644 --- a/packages/xstate-immer/test/immer.test.ts +++ b/packages/xstate-immer/test/immer.test.ts @@ -22,8 +22,8 @@ describe('@xstate/immer', () => { }); const zeroState = countMachine.initialState; - const oneState = countMachine.transition(zeroState, 'INC'); - const twoState = countMachine.transition(zeroState, 'INC'); + const oneState = countMachine.transition(zeroState, { type: 'INC' }); + const twoState = countMachine.transition(zeroState, { type: 'INC' }); expect(zeroState.context).toEqual({ count: 0 }); expect(oneState.context).toEqual({ count: 1 }); @@ -57,7 +57,7 @@ describe('@xstate/immer', () => { ); const zeroState = countMachine.initialState; - const twoState = countMachine.transition(zeroState, 'INC_TWICE'); + const twoState = countMachine.transition(zeroState, { type: 'INC_TWICE' }); expect(zeroState.context).toEqual({ count: 0 }); expect(twoState.context).toEqual({ count: 2 }); @@ -94,7 +94,7 @@ describe('@xstate/immer', () => { ); const zeroState = countMachine.initialState; - const twoState = countMachine.transition(zeroState, 'INC_TWICE'); + const twoState = countMachine.transition(zeroState, { type: 'INC_TWICE' }); expect(zeroState.context.foo.bar.baz).toEqual([1, 2, 3]); expect(twoState.context.foo.bar.baz).toEqual([1, 2, 3, 0, 0]); @@ -206,6 +206,6 @@ describe('@xstate/immer', () => { service.send(nameUpdater.update('David')); service.send(ageUpdater.update(0)); - service.send('SUBMIT'); + service.send({ type: 'SUBMIT' }); }); }); diff --git a/packages/xstate-inspect/examples/server.ts b/packages/xstate-inspect/examples/server.ts index 93654c0e07..826683562f 100644 --- a/packages/xstate-inspect/examples/server.ts +++ b/packages/xstate-inspect/examples/server.ts @@ -35,7 +35,7 @@ const machine = createMachine({ } }, active: { - entry: send('PING', { to: 'ponger', delay: 1000 }), + entry: send({ type: 'PING' }, { to: 'ponger', delay: 1000 }), on: { PONG: 'inactive' } diff --git a/packages/xstate-inspect/src/browser.ts b/packages/xstate-inspect/src/browser.ts index 68b2f7784e..15e192d7f0 100644 --- a/packages/xstate-inspect/src/browser.ts +++ b/packages/xstate-inspect/src/browser.ts @@ -4,7 +4,6 @@ import { EventObject, interpret, Observer, - toEventObject, toObserver, toSCXMLEvent } from 'xstate'; @@ -172,16 +171,14 @@ export function inspect(options?: InspectorOptions): Inspector | undefined { // while the sent one is being processed, which throws the order off const originalSend = service.send.bind(service); - service.send = function inspectSend(event: EventObject, payload?: any) { + service.send = function inspectSend(event: EventObject) { inspectService.send({ type: 'service.event', - event: stringifyWithSerializer( - toSCXMLEvent(toEventObject(event as EventObject, payload)) - ), + event: stringifyWithSerializer(toSCXMLEvent(event)), sessionId: service.sessionId }); - return originalSend(event, payload); + return originalSend(event); }; } @@ -236,7 +233,7 @@ export function inspect(options?: InspectorOptions): Inspector | undefined { }; }, disconnect: () => { - inspectService.send('disconnect'); + inspectService.send({ type: 'disconnect' }); window.removeEventListener('message', messageHandler); sub.unsubscribe(); } diff --git a/packages/xstate-inspect/src/server.ts b/packages/xstate-inspect/src/server.ts index ae57c375dc..4d374fec3b 100644 --- a/packages/xstate-inspect/src/server.ts +++ b/packages/xstate-inspect/src/server.ts @@ -4,7 +4,6 @@ import { EventObject, interpret, Interpreter, - toEventObject, toSCXMLEvent } from 'xstate'; import { toActorRef } from 'xstate/actors'; @@ -102,16 +101,14 @@ export function inspect(options: ServerInspectorOptions): Inspector { // while the sent one is being processed, which throws the order off const originalSend = service.send.bind(service); - service.send = function inspectSend(event: EventObject, payload?: any) { + service.send = function inspectSend(event: EventObject) { inspectService.send({ type: 'service.event', - event: stringify( - toSCXMLEvent(toEventObject(event as EventObject, payload)) - ), + event: stringify(toSCXMLEvent(event)), sessionId: service.sessionId }); - return originalSend(event, payload); + return originalSend(event); }; service.subscribe((state) => { diff --git a/packages/xstate-react/test/useActor.test.tsx b/packages/xstate-react/test/useActor.test.tsx index 5463cd0fa1..def4434b64 100644 --- a/packages/xstate-react/test/useActor.test.tsx +++ b/packages/xstate-react/test/useActor.test.tsx @@ -69,7 +69,7 @@ describeEachReactMode('useActor (%s)', ({ render, suiteKey }) => { states: { active: { on: { - FINISH: { actions: sendParent('FINISH') } + FINISH: { actions: sendParent({ type: 'FINISH' }) } } } } @@ -180,7 +180,7 @@ describeEachReactMode('useActor (%s)', ({ render, suiteKey }) => { states: { active: { on: { - FINISH: { actions: sendParent('FINISH') } + FINISH: { actions: sendParent({ type: 'FINISH' }) } } } } @@ -409,9 +409,9 @@ describeEachReactMode('useActor (%s)', ({ render, suiteKey }) => {
{ - send('INC'); + send({ type: 'INC' }); // @ts-expect-error - send('FAKE'); + send({ type: 'FAKE' }); }} > {state.context.count} @@ -478,7 +478,7 @@ describeEachReactMode('useActor (%s)', ({ render, suiteKey }) => {
{childState.value}
); diff --git a/packages/xstate-react/test/useInterpret.test.tsx b/packages/xstate-react/test/useInterpret.test.tsx index ba82752cc0..6d893283f7 100644 --- a/packages/xstate-react/test/useInterpret.test.tsx +++ b/packages/xstate-react/test/useInterpret.test.tsx @@ -68,7 +68,7 @@ describeEachReactMode('useInterpret (%s)', ({ suiteKey, render }) => { ); @@ -104,7 +104,7 @@ describeEachReactMode('useInterpret (%s)', ({ suiteKey, render }) => { }); React.useLayoutEffect(() => { - service.send('EXEC_ACTION'); + service.send({ type: 'EXEC_ACTION' }); }); return null; @@ -152,7 +152,7 @@ describeEachReactMode('useInterpret (%s)', ({ suiteKey, render }) => { ; + return ; case 'loading': return
Loading...
; case 'success': @@ -119,7 +119,7 @@ describeEachReactMode('useMachine, fsm (%s)', ({ suiteKey, render }) => { ; + return ; case 'loading': return
Loading...
; case 'success': @@ -384,7 +384,7 @@ describeEachReactMode('useMachine (%s)', ({ suiteKey, render }) => { + ); }; @@ -927,7 +927,10 @@ describeEachReactMode('useMachine (%s)', ({ suiteKey, render }) => { currentState = state; return ( - + ); }; @@ -968,12 +971,12 @@ describeEachReactMode('useMachine (%s)', ({ suiteKey, render }) => { context: { count: 0 }, - entry: [assign({ count: 1 }), send('INC')], + entry: [assign({ count: 1 }), send({ type: 'INC' })], on: { INC: { actions: [ assign({ count: (ctx) => ctx.count + 1 }), - send('UNHANDLED') + send({ type: 'UNHANDLED' }) ] } }, diff --git a/packages/xstate-react/test/useSelector.test.tsx b/packages/xstate-react/test/useSelector.test.tsx index 33761ccf2f..56dd7b9ab0 100644 --- a/packages/xstate-react/test/useSelector.test.tsx +++ b/packages/xstate-react/test/useSelector.test.tsx @@ -51,11 +51,11 @@ describeEachReactMode('useSelector (%s)', ({ suiteKey, render }) => {
{count}
); diff --git a/packages/xstate-react/test/useService-fsm.test.tsx b/packages/xstate-react/test/useService-fsm.test.tsx index 4f5e8698d4..3653ad56fa 100644 --- a/packages/xstate-react/test/useService-fsm.test.tsx +++ b/packages/xstate-react/test/useService-fsm.test.tsx @@ -45,7 +45,7 @@ describeEachReactMode('useService, fsm (%s)', ({ render }) => { }); act(() => { - counterService.send('INC'); + counterService.send({ type: 'INC' }); }); countEls.forEach((countEl) => { @@ -66,7 +66,7 @@ describeEachReactMode('useService, fsm (%s)', ({ render }) => { return ( <> - + {:else if $state.matches('loading')}
Loading...
{:else if $state.matches('success')} diff --git a/packages/xstate-svelte/test/UseMachine.svelte b/packages/xstate-svelte/test/UseMachine.svelte index a90fac2c9c..1cd0ea8df8 100644 --- a/packages/xstate-svelte/test/UseMachine.svelte +++ b/packages/xstate-svelte/test/UseMachine.svelte @@ -19,7 +19,7 @@
{#if $state.matches('idle')} - + {:else if $state.matches('loading')}
Loading...
{:else if $state.matches('success')} diff --git a/packages/xstate-svelte/test/UseSelector.svelte b/packages/xstate-svelte/test/UseSelector.svelte index de1b803776..2313145804 100644 --- a/packages/xstate-svelte/test/UseSelector.svelte +++ b/packages/xstate-svelte/test/UseSelector.svelte @@ -40,10 +40,12 @@ $: $service.context.count && withoutSelector++; - - diff --git a/packages/xstate-vue/src/fsm.ts b/packages/xstate-vue/src/fsm.ts index d7c627f877..53f2352820 100644 --- a/packages/xstate-vue/src/fsm.ts +++ b/packages/xstate-vue/src/fsm.ts @@ -95,7 +95,8 @@ export function useService< } ); - const send = (event: TEvent | TEvent['type']) => serviceRef.value.send(event); + const send: typeof serviceRef.value.send = (event) => + serviceRef.value.send(event); return { state, send, service: serviceRef }; } diff --git a/packages/xstate-vue/src/useActor.ts b/packages/xstate-vue/src/useActor.ts index c0c9e46e80..25adb1186a 100644 --- a/packages/xstate-vue/src/useActor.ts +++ b/packages/xstate-vue/src/useActor.ts @@ -1,4 +1,4 @@ -import { ActorRef, EventObject, Sender, SnapshotFrom } from 'xstate'; +import { ActorRef, EventObject, SnapshotFrom } from 'xstate'; import { shallowRef, isRef, watch, Ref } from 'vue'; const noop = () => { @@ -13,17 +13,17 @@ export function useActor>( }; export function useActor( actorRef: ActorRef | Ref> -): { state: Ref; send: Sender }; +): { state: Ref; send: (event: TEvent) => void }; export function useActor( actorRef: ActorRef | Ref> ): { state: Ref; - send: Sender; + send: (event: EventObject) => void; } { const actorRefRef = isRef(actorRef) ? actorRef : shallowRef(actorRef); const state = shallowRef(actorRefRef.value.getSnapshot()); - const send: Sender = (event: EventObject) => { + const send: typeof actorRefRef.value.send = (event) => { actorRefRef.value.send(event); }; diff --git a/packages/xstate-vue/test/UseActor.vue b/packages/xstate-vue/test/UseActor.vue index c5a5c9f879..fabbd47fa8 100644 --- a/packages/xstate-vue/test/UseActor.vue +++ b/packages/xstate-vue/test/UseActor.vue @@ -18,7 +18,7 @@ const childMachine = createMachine({ states: { active: { on: { - FINISH: { actions: sendParent('FINISH') } + FINISH: { actions: sendParent({ type: 'FINISH' }) } } } } diff --git a/packages/xstate-vue/test/UseActorComponentProp.vue b/packages/xstate-vue/test/UseActorComponentProp.vue index 2380046382..82491ecbd2 100644 --- a/packages/xstate-vue/test/UseActorComponentProp.vue +++ b/packages/xstate-vue/test/UseActorComponentProp.vue @@ -19,7 +19,7 @@ export default defineComponent({ } }, setup(props) { - const { state: actorState, send: actorSend } = useActor(props.actor); + const { state: actorState, send: actorSend } = useActor(props.actor!); onMounted(() => { actorSend({ type: 'FINISH' }); diff --git a/packages/xstate-vue/test/UseFSM.vue b/packages/xstate-vue/test/UseFSM.vue index 2f19978151..6b5900fd29 100644 --- a/packages/xstate-vue/test/UseFSM.vue +++ b/packages/xstate-vue/test/UseFSM.vue @@ -1,6 +1,6 @@