Skip to content

Commit

Permalink
Root out SCXML-related wrappers (#3971)
Browse files Browse the repository at this point in the history
* Root out SCXML-related wrappers

* remove more things

* fix things

* fixed escalate

* remove redundant casts to any

* add changeset
  • Loading branch information
Andarist committed May 11, 2023
1 parent 633ca76 commit d0ba42c
Show file tree
Hide file tree
Showing 45 changed files with 308 additions and 946 deletions.
5 changes: 5 additions & 0 deletions .changeset/rotten-wombats-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': major
---

`_event` has been removed from all APIs and types. It was a wrapper structure containing the `event` that users were using directly.
28 changes: 8 additions & 20 deletions packages/core/src/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,11 @@ import type {
MachineContext,
PersistedMachineState,
Prop,
SCXML,
StateConfig,
StateValue,
TransitionDefinition
} from './types.ts';
import {
flatten,
isString,
matchesState,
toSCXMLEvent,
warn
} from './utils.ts';
import { flatten, isString, matchesState, warn } from './utils.ts';

export function isStateConfig<
TContext extends MachineContext,
Expand All @@ -39,7 +32,7 @@ export function isStateConfig<
return false;
}

return 'value' in state && '_event' in state;
return 'value' in state && 'event' in state;
}

/**
Expand All @@ -66,8 +59,7 @@ export class State<
public historyValue: Readonly<HistoryValue<TContext, TEvent>> = {};
public actions: BaseActionObject[] = [];
public event: TEvent;
public _internalQueue: Array<SCXML.Event<TEvent>>;
public _event: SCXML.Event<TEvent>;
public _internalQueue: Array<TEvent>;
public _initial: boolean = false;
/**
* Indicates whether the state has changed from the previous state. A state is considered "changed" if:
Expand Down Expand Up @@ -109,7 +101,7 @@ export class State<
{
value: stateValue.value,
context,
_event: stateValue._event,
event: stateValue.event,
actions: [],
meta: {},
configuration: [], // TODO: fix,
Expand All @@ -123,7 +115,7 @@ export class State<
return stateValue;
}

const _event = createInitEvent({}) as unknown as SCXML.Event<TEvent>; // TODO: fix
const event = createInitEvent({}) as unknown as TEvent; // TODO: fix

const configuration = getConfiguration(
getStateNodes(machine.root, stateValue)
Expand All @@ -133,7 +125,7 @@ export class State<
{
value: stateValue,
context,
_event,
event,
actions: [],
meta: undefined,
configuration: Array.from(configuration),
Expand All @@ -154,9 +146,8 @@ export class State<
public machine: AnyStateMachine
) {
this.context = config.context;
this._event = config._event;
this._internalQueue = config._internalQueue ?? [];
this.event = this._event.data;
this.event = config.event;
this.historyValue = config.historyValue || {};
this.actions = config.actions ?? [];
this.matches = this.matches.bind(this);
Expand Down Expand Up @@ -242,10 +233,7 @@ export class State<
);
}

const transitionData = this.machine.getTransitionData(
this,
toSCXMLEvent(event)
);
const transitionData = this.machine.getTransitionData(this, event);

return (
!!transitionData?.length &&
Expand Down
51 changes: 22 additions & 29 deletions packages/core/src/StateMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,16 @@ import type {
MachineImplementationsSimplified,
MachineTypes,
NoInfer,
SCXML,
StateConfig,
StateMachineDefinition,
StateValue,
TransitionDefinition,
PersistedMachineState,
ParameterizedObject,
AnyActorContext
AnyActorContext,
AnyEventObject
} from './types.ts';
import {
isSCXMLErrorEvent,
resolveReferencedActor,
toSCXMLEvent
} from './utils.ts';
import { isErrorEvent, resolveReferencedActor } from './utils.ts';

export const NULL_EVENT = '';
export const STATE_IDENTIFIER = '#';
Expand Down Expand Up @@ -77,7 +73,7 @@ export class StateMachine<
>
> implements
ActorBehavior<
TEvent | SCXML.Event<TEvent>,
TEvent,
State<TContext, TEvent, TResolvedTypesMeta>,
State<TContext, TEvent, TResolvedTypesMeta>,
PersistedMachineState<State<TContext, TEvent, TResolvedTypesMeta>>
Expand Down Expand Up @@ -237,23 +233,20 @@ export class StateMachine<
public transition(
state: State<TContext, TEvent, TResolvedTypesMeta> | StateValue = this
.initialState,
event: TEvent | SCXML.Event<TEvent>,
event: TEvent,
actorCtx?: ActorContext<TEvent, State<TContext, TEvent, any>>
): State<TContext, TEvent, TResolvedTypesMeta> {
const currentState =
state instanceof State ? state : this.resolveStateValue(state);
// TODO: handle error events in a better way
const scxmlEvent = toSCXMLEvent(event);
if (
isSCXMLErrorEvent(scxmlEvent) &&
!currentState.nextEvents.some(
(nextEvent) => nextEvent === scxmlEvent.name
)
isErrorEvent(event) &&
!currentState.nextEvents.some((nextEvent) => nextEvent === event.type)
) {
throw scxmlEvent.data.data;
throw event.data;
}

const { state: nextState } = macrostep(currentState, scxmlEvent, actorCtx);
const { state: nextState } = macrostep(currentState, event, actorCtx);

return nextState;
}
Expand All @@ -267,21 +260,17 @@ export class StateMachine<
*/
public microstep(
state: State<TContext, TEvent, TResolvedTypesMeta> = this.initialState,
event: TEvent | SCXML.Event<TEvent>,
event: TEvent,
actorCtx?: AnyActorContext | undefined
): Array<State<TContext, TEvent, TResolvedTypesMeta>> {
const scxmlEvent = toSCXMLEvent(event);

const { microstates } = macrostep(state, scxmlEvent, actorCtx);

return microstates;
return macrostep(state, event, actorCtx).microstates;
}

public getTransitionData(
state: State<TContext, TEvent, TResolvedTypesMeta>,
_event: SCXML.Event<TEvent>
event: TEvent
): Array<TransitionDefinition<TContext, TEvent>> {
return transitionNode(this.root, state.value, state, _event) || [];
return transitionNode(this.root, state.value, state, event) || [];
}

/**
Expand All @@ -298,7 +287,7 @@ export class StateMachine<
this.createState({
value: {}, // TODO: this is computed in state constructor
context,
_event: createInitEvent({}) as unknown as SCXML.Event<TEvent>,
event: createInitEvent({}) as unknown as TEvent,
actions: [],
meta: undefined,
configuration: config,
Expand All @@ -312,7 +301,7 @@ export class StateMachine<
if (actorCtx) {
const { nextState } = resolveActionsAndContext(
actions,
initEvent as SCXML.Event<TEvent>,
initEvent as TEvent,
preInitial,
actorCtx
);
Expand Down Expand Up @@ -341,13 +330,17 @@ export class StateMachine<
>,
input?: any
): State<TContext, TEvent, TResolvedTypesMeta> {
const initEvent = createInitEvent(input) as unknown as SCXML.Event<TEvent>; // TODO: fix;
const initEvent = createInitEvent(input) as unknown as TEvent; // TODO: fix;

const preInitialState = this.getPreInitialState(actorCtx, input);
const nextState = microstep([], preInitialState, actorCtx, initEvent);
nextState.actions.unshift(...preInitialState.actions);

const { state: macroState } = macrostep(nextState, initEvent, actorCtx);
const { state: macroState } = macrostep(
nextState,
initEvent as AnyEventObject,
actorCtx
);

return macroState;
}
Expand Down Expand Up @@ -414,7 +407,7 @@ export class StateMachine<

const { nextState: resolvedState } = resolveActionsAndContext(
state.actions,
state._event,
state.event,
state,
undefined
);
Expand Down
20 changes: 7 additions & 13 deletions packages/core/src/StateNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import type {
InvokeDefinition,
Mapper,
PropertyMapper,
SCXML,
TransitionDefinitionMap,
InitialTransitionDefinition,
MachineContext,
Expand Down Expand Up @@ -115,7 +114,7 @@ export class StateNode<
| Mapper<TContext, TEvent, any>
| PropertyMapper<TContext, TEvent, any>;
/**
* The order this state node appears. Corresponds to the implicit SCXML document order.
* The order this state node appears. Corresponds to the implicit document order.
*/
public order: number = -1;

Expand Down Expand Up @@ -335,20 +334,20 @@ export class StateNode<

public next(
state: State<TContext, TEvent>,
_event: SCXML.Event<TEvent>
event: TEvent
): TransitionDefinition<TContext, TEvent>[] | undefined {
const eventName = _event.name;
const eventType = event.type;
const actions: BaseActionObject[] = [];

let selectedTransition: TransitionDefinition<TContext, TEvent> | undefined;

const candidates: Array<TransitionDefinition<TContext, TEvent>> = memo(
this,
`candidates-${eventName.toString()}`,
`candidates-${eventType.toString()}`,
() =>
getCandidates(
this,
eventName,
eventType,
this.machine.config.scxml // Whether token matching should be used
)
);
Expand All @@ -362,17 +361,12 @@ export class StateNode<
try {
guardPassed =
!guard ||
evaluateGuard<TContext, TEvent>(
guard,
resolvedContext,
_event,
state
);
evaluateGuard<TContext, TEvent>(guard, resolvedContext, event, state);
} catch (err) {
throw new Error(
`Unable to evaluate guard '${
guard!.type
}' in transition for event '${eventName}' in state node '${
}' in transition for event '${eventType}' in state node '${
this.id
}':\n${err.message}`
);
Expand Down
24 changes: 9 additions & 15 deletions packages/core/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import {
ErrorPlatformEvent,
DoneEventObject,
MachineContext,
BaseActionObject,
SCXML
BaseActionObject
} from './types.ts';
import * as actionTypes from './actionTypes.ts';
import { toSCXMLEvent, isArray } from './utils.ts';
import { isArray } from './utils.ts';
import {
createDynamicAction,
isDynamicAction
Expand All @@ -22,7 +21,6 @@ export {
send,
sendTo,
sendParent,
respond,
forwardTo,
escalate
} from './actions/send.ts';
Expand All @@ -36,7 +34,7 @@ export { choose } from './actions/choose.ts';
export { pure } from './actions/pure.ts';
export { actionTypes };

export const initEvent = toSCXMLEvent({ type: actionTypes.init });
export const initEvent = { type: actionTypes.init };

export function resolveActionObject(
actionObject: BaseActionObject,
Expand All @@ -50,16 +48,15 @@ export function resolveActionObject(
if (typeof dereferencedAction === 'function') {
return createDynamicAction(
{ type: 'xstate.function', params: actionObject.params ?? {} },
(_event, { state }) => {
(event, { state }) => {
const a: BaseActionObject = {
type: actionObject.type,
params: actionObject.params,
execute: (actorCtx) => {
return dereferencedAction({
context: state.context,
event: _event.data,
event,
action: a,
_event: _event,
system: actorCtx.system,
self: actorCtx.self
});
Expand Down Expand Up @@ -92,7 +89,7 @@ export function toActionObject<

if (typeof action === 'function') {
const type = 'xstate.function';
return createDynamicAction({ type, params: {} }, (_event, { state }) => {
return createDynamicAction({ type, params: {} }, (event, { state }) => {
const actionObject: BaseActionObject = {
type,
params: {
Expand All @@ -101,9 +98,8 @@ export function toActionObject<
execute: (actorCtx) => {
return action({
context: state.context as TContext,
event: _event.data as TEvent,
event: event as TEvent,
action: actionObject,
_event: _event as SCXML.Event<TEvent>,
self: actorCtx.self,
system: actorCtx.system
});
Expand Down Expand Up @@ -192,8 +188,6 @@ export function error(id: string, data?: any): ErrorPlatformEvent & string {
return eventObject as ErrorPlatformEvent & string;
}

export function createInitEvent(
input: any
): SCXML.Event<{ type: ActionTypes.Init; input: any }> {
return toSCXMLEvent({ type: actionTypes.init, input });
export function createInitEvent(input: any) {
return { type: actionTypes.init, input } as const;
}
7 changes: 3 additions & 4 deletions packages/core/src/actions/assign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function assign<
assignment
}
},
(_event, { state, action, actorContext }) => {
(event, { state, action, actorContext }) => {
const capturedActions: InvokeActionObject[] = [];

if (!state.context) {
Expand All @@ -58,14 +58,13 @@ export function assign<
event: TExpressionEvent;
} = {
context: state.context,
event: _event.data,
event,
action,
_event,
spawn: createSpawner(
actorContext?.self,
state.machine,
state.context,
_event,
event,
capturedActions
),
self: actorContext?.self ?? ({} as any),
Expand Down
Loading

0 comments on commit d0ba42c

Please sign in to comment.