Skip to content

Commit

Permalink
Final .data to .output (#3952)
Browse files Browse the repository at this point in the history
* Rename final.data to final.output

* Add changeset

* Update .changeset/five-mirrors-join.md

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>

* Rename doneData -> output

* Cleanup

* Fix types

* .data -> .output

* Typecheck

* Tweak typegen types

---------

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
  • Loading branch information
davidkpiano and Andarist committed Apr 8, 2023
1 parent 2f45343 commit ec30083
Show file tree
Hide file tree
Showing 19 changed files with 109 additions and 91 deletions.
18 changes: 18 additions & 0 deletions .changeset/five-mirrors-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'xstate': major
---

The output data on final states is now specified as `.output` instead of `.data`:

```diff
const machine = createMachine({
// ...
states: {
// ...
success: {
- data: { message: 'Success!' }
+ output: { message: 'Success!' }
}
}
})
```
10 changes: 5 additions & 5 deletions packages/core/src/StateNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ export class StateNode<
*/
public meta?: any;
/**
* The data sent with the "done.state._id_" event if this is a final state node.
* The output data sent with the "done.state._id_" event if this is a final state node.
*/
public doneData?:
public output?:
| Mapper<TContext, TEvent, any>
| PropertyMapper<TContext, TEvent, any>;
/**
Expand Down Expand Up @@ -185,9 +185,9 @@ export class StateNode<
this.exit = toActionObjects(this.config.exit);

this.meta = this.config.meta;
this.doneData =
this.output =
this.type === 'final'
? (this.config as FinalStateNodeConfig<TContext, TEvent>).data
? (this.config as FinalStateNodeConfig<TContext, TEvent>).output
: undefined;
this.tags = toArray(config.tags);
}
Expand Down Expand Up @@ -239,7 +239,7 @@ export class StateNode<
exit: this.exit,
meta: this.meta,
order: this.order || -1,
data: this.doneData,
output: this.output,
invoke: this.invoke,
description: this.description,
tags: this.tags
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,13 @@ export function after(delayRef: number | string, id?: string) {
* has been reached in the parent state node.
*
* @param id The final state node's parent state node `id`
* @param data The data to pass into the event
* @param output The data to pass into the event
*/
export function done(id: string, data?: any): DoneEventObject {
export function done(id: string, output?: any): DoneEventObject {
const type = `${ActionTypes.DoneState}.${id}`;
const eventObject = {
type,
data
output
};

eventObject.toString = () => type;
Expand All @@ -168,13 +168,13 @@ export function done(id: string, data?: any): DoneEventObject {
* but not when it is canceled.
*
* @param invokeId The invoked service ID
* @param data The data to pass into the event
* @param output The data to pass into the event
*/
export function doneInvoke(invokeId: string, data?: any): DoneEvent {
export function doneInvoke(invokeId: string, output?: any): DoneEvent {
const type = `${ActionTypes.DoneInvoke}.${invokeId}`;
const eventObject = {
type,
data
output
};

eventObject.toString = () => type;
Expand Down
13 changes: 5 additions & 8 deletions packages/core/src/stateUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,9 @@ function getOutput<TContext extends MachineContext, TEvent extends EventObject>(
stateNode.type === 'final' && stateNode.parent === machine.root
);

const doneData =
finalChildStateNode && finalChildStateNode.doneData
? mapContext(finalChildStateNode.doneData, context, _event)
: undefined;

return doneData;
return finalChildStateNode && finalChildStateNode.output
? mapContext(finalChildStateNode.output, context, _event)
: undefined;
}

const isAtomicStateNode = (stateNode: StateNode<any, any>) =>
Expand Down Expand Up @@ -1272,9 +1269,9 @@ function enterStates(
toSCXMLEvent(
done(
parent!.id,
stateNodeToEnter.doneData
stateNodeToEnter.output
? mapContext(
stateNodeToEnter.doneData,
stateNodeToEnter.output,
currentState.context,
currentState._event
)
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/typegenTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,11 @@ export interface ResolveTypegenMeta<
AllowAllEvents & {
indexedActions: IndexByType<TAction>;
indexedEvents: Record<string, TEvent> & {
__XSTATE_ALLOW_ANY_INVOKE_DATA_HACK__: { data: any };
__XSTATE_ALLOW_ANY_INVOKE_OUTPUT_HACK__: { output: any };
};
invokeSrcNameMap: Record<
string,
'__XSTATE_ALLOW_ANY_INVOKE_DATA_HACK__'
'__XSTATE_ALLOW_ANY_INVOKE_OUTPUT_HACK__'
>;
};
}[IsNever<TTypesMeta> extends true
Expand Down
22 changes: 13 additions & 9 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ export interface InvokeConfig<
onError?:
| string
| SingleOrArray<
TransitionConfigOrTarget<TContext, DoneInvokeEvent<any>, TEvent>
TransitionConfigOrTarget<TContext, ErrorEvent<any>, TEvent>
>;

onSnapshot?:
Expand Down Expand Up @@ -643,12 +643,14 @@ export interface StateNodeConfig<
*/
meta?: any;
/**
* The data sent with the "done.state._id_" event if this is a final state node.
* The output data sent with the "done.state._id_" event if this is a final state node.
*
* The data will be evaluated with the current `context` and placed on the `.data` property
* The output data will be evaluated with the current `context` and placed on the `.data` property
* of the event.
*/
data?: Mapper<TContext, TEvent, any> | PropertyMapper<TContext, TEvent, any>;
output?:
| Mapper<TContext, TEvent, any>
| PropertyMapper<TContext, TEvent, any>;
/**
* The unique ID of the state node, which can be referenced as a transition target via the
* `#id` syntax.
Expand Down Expand Up @@ -695,7 +697,7 @@ export interface StateNodeDefinition<
exit: BaseActionObject[];
meta: any;
order: number;
data?: FinalStateNodeConfig<TContext, TEvent>['data'];
output?: FinalStateNodeConfig<TContext, TEvent>['output'];
invoke: Array<InvokeDefinition<TContext, TEvent>>;
description?: string;
tags: string[];
Expand Down Expand Up @@ -745,7 +747,9 @@ export interface FinalStateNodeConfig<
* The data to be sent with the "done.state.<id>" event. The data can be
* static or dynamic (based on assigners).
*/
data?: Mapper<TContext, TEvent, any> | PropertyMapper<TContext, TEvent, any>;
output?:
| Mapper<TContext, TEvent, any>
| PropertyMapper<TContext, TEvent, any>;
}

export type SimpleOrStateNodeConfig<
Expand Down Expand Up @@ -1025,7 +1029,7 @@ export interface MachineConfig<
tsTypes?: TTypesMeta;
}

export type ActorMap = Record<string, { data: any }>;
export type ActorMap = Record<string, { output: any }>;
export interface MachineSchema<
TContext extends MachineContext,
TEvent extends EventObject,
Expand Down Expand Up @@ -1100,7 +1104,7 @@ export interface RaiseActionObject<

export interface DoneInvokeEvent<TData> extends EventObject {
type: `done.invoke.${string}`;
data: TData;
output: TData;
}

export interface ErrorEvent<TErrorData> {
Expand Down Expand Up @@ -1132,7 +1136,7 @@ export interface SCXMLErrorEvent extends SCXML.Event<any> {
}

export interface DoneEventObject extends EventObject {
data?: any;
output?: any;
toString(): string;
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/test/actor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ describe('spawning promises', () => {
on: {
[doneInvoke('my-promise')]: {
target: 'success',
guard: ({ event }) => event.data === 'response'
guard: ({ event }) => event.output === 'response'
}
}
},
Expand Down Expand Up @@ -282,7 +282,7 @@ describe('spawning promises', () => {
on: {
[doneInvoke('my-promise')]: {
target: 'success',
guard: ({ event }) => event.data === 'response'
guard: ({ event }) => event.output === 'response'
}
}
},
Expand Down Expand Up @@ -915,7 +915,7 @@ describe('actors', () => {
on: {
'done.invoke.test': {
target: 'success',
guard: ({ event }) => event.data === 42
guard: ({ event }) => event.output === 42
}
}
},
Expand Down
15 changes: 5 additions & 10 deletions packages/core/test/final.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
createMachine,
interpret,
assign,
AnyEventObject
} from '../src/index.ts';
import { createMachine, interpret, assign } from '../src/index.ts';

describe('final states', () => {
it('should emit the "done.state.*" event when all nested states are in their final states', () => {
Expand Down Expand Up @@ -117,16 +112,16 @@ describe('final states', () => {
},
reveal: {
type: 'final',
data: {
output: {
secret: () => 'the secret'
}
}
},
onDone: {
target: 'success',
actions: assign<Ctx, AnyEventObject>({
actions: assign({
revealedSecret: ({ event }) => {
return event.data.secret;
return event.output.secret;
}
})
}
Expand Down Expand Up @@ -161,7 +156,7 @@ describe('final states', () => {
},
end: {
type: 'final',
data: spy
output: spy
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/interpreter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1632,7 +1632,7 @@ describe('interpreter', () => {
{
target: 'success',
guard: ({ event }) => {
return event.data === 42;
return event.output === 42;
}
},
{ target: 'failure' }
Expand Down

0 comments on commit ec30083

Please sign in to comment.