Skip to content

Commit

Permalink
Switch to resolveState method
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Nov 10, 2023
1 parent a299b3e commit 210beb0
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 43 deletions.
31 changes: 21 additions & 10 deletions packages/core/src/StateMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ import type {
TODO,
SnapshotFrom,
Snapshot,
AnyActorLogic
AnyActorLogic,
HistoryValue
} from './types.ts';
import { isErrorActorEvent, resolveReferencedActor } from './utils.ts';
import { $$ACTOR_TYPE, createActor } from './interpreter.ts';
Expand Down Expand Up @@ -248,11 +249,17 @@ export class StateMachine<
});
}

public resolveStateValue(
stateValue: StateValue,
...[context]: Equals<TContext, MachineContext> extends true
? []
: [TContext]
public resolveState(
config: {
value: StateValue;
context?: TContext;
historyValue?: HistoryValue<TContext, TEvent>;
status?: 'active' | 'done' | 'error' | 'stopped';
output?: TOutput;
error?: unknown;
} & (Equals<TContext, MachineContext> extends false
? { context: unknown }
: {})
): MachineSnapshot<
TContext,
TEvent,
Expand All @@ -261,17 +268,22 @@ export class StateMachine<
TOutput,
TResolvedTypesMeta
> {
const resolvedStateValue = resolveStateValue(this.root, stateValue);
const resolvedStateValue = resolveStateValue(this.root, config.value);
const configurationSet = getConfiguration(
getStateNodes(this.root, resolvedStateValue)
);

return new State(
{
configuration: [...configurationSet],
context: (context || {}) as TContext,
context: config.context || ({} as TContext),
children: {},
status: isInFinalState(configurationSet, this.root) ? 'done' : 'active'
status: isInFinalState(configurationSet, this.root)
? 'done'
: config.status || 'active',
output: config.output,
error: config.error,
historyValue: config.historyValue
},
this
) as MachineSnapshot<
Expand Down Expand Up @@ -386,7 +398,6 @@ export class StateMachine<
{
context:
typeof context !== 'function' && context ? context : ({} as TContext),
meta: undefined,
configuration: getInitialConfiguration(this.root),
children: {},
status: 'active'
Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1657,13 +1657,11 @@ export interface StateConfig<
> {
context: TContext;
historyValue?: HistoryValue<TContext, TEvent>;
meta?: any;
configuration: Array<StateNode<TContext, TEvent>>;
children: Record<string, ActorRef<any, any>>;
status: 'active' | 'done' | 'error' | 'stopped';
output?: any;
error?: unknown;
tags?: Set<string>;
machine?: StateMachine<TContext, TEvent, any, any, any, any, any, any, any>;
}

Expand Down
22 changes: 11 additions & 11 deletions packages/core/test/deterministic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(
lightMachine.transition(
lightMachine.resolveStateValue('green'),
lightMachine.resolveState({ value: 'green' }),
{
type: 'TIMER'
},
Expand Down Expand Up @@ -102,7 +102,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(() =>
lightMachine.transition(
testMachine.resolveStateValue('red'),
testMachine.resolveState({ value: 'red' }),
undefined as any,
actorScope
)
Expand All @@ -113,7 +113,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(
testMachine.transition(
testMachine.resolveStateValue('a'),
testMachine.resolveState({ value: 'a' }),
{ type: 'T' },
actorScope
).value
Expand All @@ -126,7 +126,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(() =>
testMachine.transition(
testMachine.resolveStateValue('fake'),
testMachine.resolveState({ value: 'fake' }),
{ type: 'T' },
actorScope
)
Expand All @@ -137,7 +137,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(() =>
testMachine.transition(
testMachine.resolveStateValue('a.fake'),
testMachine.resolveState({ value: 'a.fake' }),
{
type: 'T'
},
Expand Down Expand Up @@ -175,7 +175,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(
lightMachine.transition(
lightMachine.resolveStateValue({ red: 'walk' }),
lightMachine.resolveState({ value: { red: 'walk' } }),
{ type: 'PED_COUNTDOWN' },
actorScope
).value
Expand All @@ -186,7 +186,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(
lightMachine.transition(
lightMachine.resolveStateValue('red'),
lightMachine.resolveState({ value: 'red' }),
{
type: 'PED_COUNTDOWN'
},
Expand All @@ -201,7 +201,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(
lightMachine.transition(
lightMachine.resolveStateValue('red'),
lightMachine.resolveState({ value: 'red' }),
{
type: 'PED_COUNTDOWN'
},
Expand All @@ -216,7 +216,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(
lightMachine.transition(
lightMachine.resolveStateValue({ red: 'stop' }),
lightMachine.resolveState({ value: { red: 'stop' } }),
{ type: 'TIMER' },
actorScope
).value
Expand Down Expand Up @@ -255,7 +255,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API
expect(
lightMachine.transition(
lightMachine.resolveStateValue('yellow'),
lightMachine.resolveState({ value: 'yellow' }),
{
type: 'TIMER'
},
Expand Down Expand Up @@ -327,7 +327,7 @@ describe('deterministic machine', () => {
const actorScope = null as any; // TODO: figure out the simulation API

const walkState = lightMachine.transition(
lightMachine.resolveStateValue({ red: 'walk' }),
lightMachine.resolveState({ value: { red: 'walk' } }),
{ type: 'TIMER' },
actorScope
);
Expand Down
6 changes: 3 additions & 3 deletions packages/core/test/interpreter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1054,7 +1054,7 @@ describe('interpreter', () => {
}
});
const actor = createActor(machine, {
state: machine.resolveStateValue('bar')
state: machine.resolveState({ value: 'bar' })
});

expect(actor.getSnapshot().matches('bar')).toBeTruthy();
Expand All @@ -1071,7 +1071,7 @@ describe('interpreter', () => {
}
});
const actor = createActor(machine, {
state: machine.resolveStateValue('bar')
state: machine.resolveState({ value: 'bar' })
});

expect(actor.getSnapshot().matches('bar')).toBeTruthy();
Expand All @@ -1094,7 +1094,7 @@ describe('interpreter', () => {
}
});
const actor = createActor(machine, {
state: machine.resolveStateValue('foo')
state: machine.resolveState({ value: 'foo' })
});

expect(actor.getSnapshot().matches({ foo: 'one' })).toBeTruthy();
Expand Down
10 changes: 5 additions & 5 deletions packages/core/test/invalid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('invalid or resolved states', () => {
});
expect(
machine.transition(
machine.resolveStateValue('A'),
machine.resolveState({ value: 'A' }),
{ type: 'E' },
{} as any // TODO: figure out the simulation API
).value
Expand Down Expand Up @@ -55,7 +55,7 @@ describe('invalid or resolved states', () => {
});
expect(
machine.transition(
machine.resolveStateValue({ A: {}, B: {} }),
machine.resolveState({ value: { A: {}, B: {} } }),
{ type: 'E' },
{} as any // TODO: figure out the simulation API
).value
Expand Down Expand Up @@ -86,7 +86,7 @@ describe('invalid or resolved states', () => {
}
});
machine.transition(
machine.resolveStateValue({ A: 'A1', B: 'B1' }),
machine.resolveState({ value: { A: 'A1', B: 'B1' } }),
{ type: 'E' },
{} as any // TODO: figure out the simulation API
);
Expand Down Expand Up @@ -114,7 +114,7 @@ describe('invalid or resolved states', () => {
});
expect(() =>
machine.transition(
machine.resolveStateValue({ A: 'A3', B: 'B3' }),
machine.resolveState({ value: { A: 'A3', B: 'B3' } }),
{ type: 'E' },
{} as any // TODO: figure out the simulation API
)
Expand Down Expand Up @@ -143,7 +143,7 @@ describe('invalid or resolved states', () => {
});
expect(
machine.transition(
machine.resolveStateValue({ A: 'A1', B: {} }),
machine.resolveState({ value: { A: 'A1', B: {} } }),
{ type: 'E' },
{} as any // TODO: figure out the simulation API
).value
Expand Down
6 changes: 3 additions & 3 deletions packages/core/test/machine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,15 @@ describe('machine', () => {
});

it('should resolve the state value', () => {
const resolvedState = resolveMachine.resolveStateValue('foo');
const resolvedState = resolveMachine.resolveState({ value: 'foo' });

expect(resolvedState.value).toEqual({
foo: { one: { a: 'aa', b: 'bb' } }
});
});

it('should resolve the state configuration (implicit via events)', () => {
const resolvedState = resolveMachine.resolveStateValue('foo');
const resolvedState = resolveMachine.resolveState({ value: 'foo' });

expect(resolvedState.nextEvents.sort()).toEqual(['TO_BAR', 'TO_TWO']);
});
Expand All @@ -309,7 +309,7 @@ describe('machine', () => {
}
});

const resolvedState = machine.resolveStateValue('bar');
const resolvedState = machine.resolveState({ value: 'bar' });

expect(resolvedState.status).toBe('done');
});
Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/meta.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ describe('state meta data', () => {
});

const actor = createActor(machine, {
state: machine.resolveStateValue('second')
state: machine.resolveState({ value: 'second' })
});
actor.start();

Expand Down
4 changes: 2 additions & 2 deletions packages/core/test/microstep.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('machine.microstep()', () => {

const actorScope = null as any; // TODO: figure out the simulation API
const states = machine.microstep(
machine.resolveStateValue('first'),
machine.resolveState({ value: 'first' }),
{ type: 'TRIGGER' },
actorScope
);
Expand Down Expand Up @@ -89,7 +89,7 @@ describe('machine.microstep()', () => {

const actorScope = null as any; // TODO: figure out the simulation API
const states = machine.microstep(
machine.resolveStateValue('first'),
machine.resolveState({ value: 'first' }),
{ type: 'TRIGGER' },
actorScope
);
Expand Down
4 changes: 2 additions & 2 deletions packages/core/test/rehydration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('rehydration', () => {
}
});

const activeState = machine.resolveStateValue('active');
const activeState = machine.resolveState({ value: 'active' });
const service = createActor(machine, {
state: activeState
});
Expand All @@ -107,7 +107,7 @@ describe('rehydration', () => {
});

createActor(machine, {
state: machine.resolveStateValue('active')
state: machine.resolveState({ value: 'active' })
})
.start()
.stop();
Expand Down
4 changes: 2 additions & 2 deletions packages/core/test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const resolveSerializedStateValue = (
serialized: string
) =>
serialized[0] === '{'
? machine.resolveStateValue(JSON.parse(serialized), {})
: machine.resolveStateValue(serialized, {});
? machine.resolveState({ value: JSON.parse(serialized), context: {} })
: machine.resolveState({ value: serialized, context: {} });

export function testMultiTransition(
machine: AnyStateMachine,
Expand Down
4 changes: 2 additions & 2 deletions packages/xstate-graph/test/graph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ describe('@xstate/graph', () => {

it('should return a path from a specified from-state', () => {
const path = getPathsFromEvents(lightMachine, [{ type: 'TIMER' }], {
fromState: lightMachine.resolveStateValue('yellow')
fromState: lightMachine.resolveState({ value: 'yellow' })
})[0];

expect(path).toBeDefined();
Expand Down Expand Up @@ -655,7 +655,7 @@ it.each([getShortestPaths, getSimplePaths])(
});

const paths = pathGetter(machine, {
fromState: machine.resolveStateValue('b')
fromState: machine.resolveState({ value: 'b' })
});

// Instead of taking 2 steps to reach state 'b' (A, B),
Expand Down

0 comments on commit 210beb0

Please sign in to comment.