Skip to content

Commit

Permalink
Strongly-typed state.value and state.matches (#4498)
Browse files Browse the repository at this point in the history
* Strongly type state value

* Satisfy the typegen

* small tweaks

* Pass around `TStateValue` instead of `TConfig`

* Type `MachineSnapshot<...>['value']` correctly

* remove code related to typegen and `state.matches`

* remove outdated comment

* first stab at `ToTestStateValue`

* add some extra ts-expect-errors

* cast `machineSnapshotMatches`

* Fixed `ToTestStateValue`

* add missing initial property

* Revert "remove code related to typegen and `state.matches`"

This reverts commit 6e19c9a.

* support typegen

* Fixed assertions in typegen tests

* add more test cases, fix one case

---------

Co-authored-by: Mateusz Burzyński <[email protected]>
  • Loading branch information
davidkpiano and Andarist authored Nov 29, 2023
1 parent daf532b commit 02e14f6
Show file tree
Hide file tree
Showing 10 changed files with 622 additions and 64 deletions.
59 changes: 45 additions & 14 deletions packages/core/src/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,36 @@ import { $$ACTOR_TYPE } from './interpreter.ts';
import type { StateNode } from './StateNode.ts';
import type { StateMachine } from './StateMachine.ts';
import { getStateValue } from './stateUtils.ts';
import { TypegenDisabled, TypegenEnabled } from './typegenTypes.ts';
import { TypegenDisabled } from './typegenTypes.ts';
import type {
ProvidedActor,
AnyMachineSnapshot,
AnyStateMachine,
EventObject,
HistoryValue,
MachineContext,
Prop,
StateConfig,
StateValue,
AnyActorRef,
EventDescriptor,
Snapshot,
ParameterizedObject
ParameterizedObject,
IsNever
} from './types.ts';
import { matchesState } from './utils.ts';

type ToTestStateValue<TStateValue extends StateValue> =
TStateValue extends string
? TStateValue
: IsNever<keyof TStateValue> extends true
? never
:
| keyof TStateValue
| {
[K in keyof TStateValue]?: ToTestStateValue<
NonNullable<TStateValue[K]>
>;
};

export function isMachineSnapshot<
TContext extends MachineContext,
TEvent extends EventObject
Expand All @@ -37,6 +49,7 @@ interface MachineSnapshotBase<
TContext extends MachineContext,
TEvent extends EventObject,
TChildren extends Record<string, AnyActorRef | undefined>,
TStateValue extends StateValue,
TTag extends string,
TOutput,
TResolvedTypesMeta = TypegenDisabled
Expand All @@ -49,13 +62,14 @@ interface MachineSnapshotBase<
ParameterizedObject,
ParameterizedObject,
string,
TStateValue,
TTag,
unknown,
TOutput,
TResolvedTypesMeta
>;
tags: Set<string>;
value: StateValue;
value: TStateValue;
status: 'active' | 'done' | 'error' | 'stopped';
error: unknown;
context: TContext;
Expand All @@ -74,20 +88,17 @@ interface MachineSnapshotBase<
* Whether the current state value is a subset of the given parent state value.
* @param testValue
*/
matches: <
TSV extends TResolvedTypesMeta extends TypegenEnabled
? Prop<Prop<TResolvedTypesMeta, 'resolved'>, 'matchesStates'>
: StateValue
>(
matches: (
this: MachineSnapshot<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
>,
testValue: TSV
testValue: ToTestStateValue<TStateValue>
) => boolean;

/**
Expand All @@ -99,6 +110,7 @@ interface MachineSnapshotBase<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -119,6 +131,7 @@ interface MachineSnapshotBase<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -131,6 +144,7 @@ interface MachineSnapshotBase<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -142,6 +156,7 @@ interface MachineSnapshotBase<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -153,13 +168,15 @@ interface ActiveMachineSnapshot<
TContext extends MachineContext,
TEvent extends EventObject,
TChildren extends Record<string, AnyActorRef | undefined>,
TStateValue extends StateValue,
TTag extends string,
TOutput,
TResolvedTypesMeta = TypegenDisabled
> extends MachineSnapshotBase<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -173,13 +190,15 @@ interface DoneMachineSnapshot<
TContext extends MachineContext,
TEvent extends EventObject,
TChildren extends Record<string, AnyActorRef | undefined>,
TStateValue extends StateValue,
TTag extends string,
TOutput,
TResolvedTypesMeta = TypegenDisabled
> extends MachineSnapshotBase<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -193,13 +212,15 @@ interface ErrorMachineSnapshot<
TContext extends MachineContext,
TEvent extends EventObject,
TChildren extends Record<string, AnyActorRef | undefined>,
TStateValue extends StateValue,
TTag extends string,
TOutput,
TResolvedTypesMeta = TypegenDisabled
> extends MachineSnapshotBase<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -213,13 +234,15 @@ interface StoppedMachineSnapshot<
TContext extends MachineContext,
TEvent extends EventObject,
TChildren extends Record<string, AnyActorRef | undefined>,
TStateValue extends StateValue,
TTag extends string,
TOutput,
TResolvedTypesMeta = TypegenDisabled
> extends MachineSnapshotBase<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -233,6 +256,7 @@ export type MachineSnapshot<
TContext extends MachineContext,
TEvent extends EventObject,
TChildren extends Record<string, AnyActorRef | undefined>,
TStateValue extends StateValue,
TTag extends string,
TOutput,
TResolvedTypesMeta = TypegenDisabled
Expand All @@ -241,6 +265,7 @@ export type MachineSnapshot<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -249,6 +274,7 @@ export type MachineSnapshot<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -257,6 +283,7 @@ export type MachineSnapshot<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand All @@ -265,6 +292,7 @@ export type MachineSnapshot<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand Down Expand Up @@ -334,6 +362,7 @@ export function createMachineSnapshot<
TContext extends MachineContext,
TEvent extends EventObject,
TChildren extends Record<string, AnyActorRef | undefined>,
TStateValue extends StateValue,
TTag extends string,
TResolvedTypesMeta = TypegenDisabled
>(
Expand All @@ -343,6 +372,7 @@ export function createMachineSnapshot<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
undefined,
TResolvedTypesMeta
Expand All @@ -354,12 +384,11 @@ export function createMachineSnapshot<
machine,
context: config.context,
_nodes: config._nodes,
value: getStateValue(machine.root, config._nodes),
value: getStateValue(machine.root, config._nodes) as never,
tags: new Set(config._nodes.flatMap((sn) => sn.tags)),
children: config.children as any,
historyValue: config.historyValue || {},
// this one is generic in the target and it's hard to create a matching non-generic source signature
matches: machineSnapshotMatches as any,
matches: machineSnapshotMatches as never,
hasTag: machineSnapshotHasTag,
can: machineSnapshotCan,
getMeta: machineSnapshotGetMeta,
Expand All @@ -381,6 +410,7 @@ export function getPersistedState<
TContext extends MachineContext,
TEvent extends EventObject,
TChildren extends Record<string, AnyActorRef | undefined>,
TStateValue extends StateValue,
TTag extends string,
TOutput,
TResolvedTypesMeta = TypegenDisabled
Expand All @@ -389,6 +419,7 @@ export function getPersistedState<
TContext,
TEvent,
TChildren,
TStateValue,
TTag,
TOutput,
TResolvedTypesMeta
Expand Down
Loading

0 comments on commit 02e14f6

Please sign in to comment.