Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
bf0f324
POC for actor types
davidkpiano May 22, 2023
a52fc3a
Merge branch 'next' into v5/machine-types-1
davidkpiano May 22, 2023
2606909
Remove patterns.ts
davidkpiano May 22, 2023
c907217
Fix types sorta
davidkpiano May 22, 2023
cb88638
Remove ActorMap
davidkpiano May 22, 2023
e6f50ba
Add changeset
davidkpiano May 23, 2023
e423623
Merge branch 'next' into v5/machine-types-1
davidkpiano May 23, 2023
1e4ba5d
Improve state.children
davidkpiano May 23, 2023
cbb0577
Add InputFrom and actor behavior input
davidkpiano May 23, 2023
18aca45
Types WIP
davidkpiano May 24, 2023
10e66cc
Merge branch 'next' into v5/machine-types-1
davidkpiano May 29, 2023
3f3abe1
PromiseActorEvents
davidkpiano May 29, 2023
6c14671
Undo
davidkpiano May 29, 2023
2e9ec56
Merge branch 'next' into v5/machine-types-1
davidkpiano Jun 1, 2023
491c659
Fix most type errors
davidkpiano Jun 1, 2023
78929ec
Get types passing
davidkpiano Jun 2, 2023
312d47d
Merge branch 'next' into v5/machine-types-1
davidkpiano Jun 8, 2023
eea6aae
Merge branch 'next' into v5/machine-types-1
davidkpiano Jun 9, 2023
e4f4c5e
Update packages/xstate-solid/test/useMachine.test.tsx
davidkpiano Jun 17, 2023
c3fd7eb
Merge branch 'next' into v5/machine-types-1
davidkpiano Jun 17, 2023
704612c
Change changeset
davidkpiano Jun 17, 2023
4f37bac
Merge branch 'v5/machine-types-1' of https://github.com/statelyai/xst…
davidkpiano Jun 17, 2023
494f2aa
Fix types
davidkpiano Jun 17, 2023
c30336a
Fix test type
davidkpiano Jun 17, 2023
6db1fbe
Clean up ActorImpl types
davidkpiano Jun 18, 2023
328c57a
Fix import
davidkpiano Jun 18, 2023
47aab9f
Merge branch 'next' into v5/machine-types-1
davidkpiano Jun 21, 2023
53db8f8
Fix import
davidkpiano Jun 21, 2023
df6fb49
Merge branch 'next' into v5/machine-types-1
davidkpiano Jun 22, 2023
ba16573
Fix
davidkpiano Jun 22, 2023
21eb12b
Merge branch 'next' into v5/machine-types-1
davidkpiano Jun 24, 2023
c86c7ef
Merge branch 'next' into v5/machine-types-1
davidkpiano Jun 25, 2023
4d8ed11
Merge branch 'next' into v5/machine-types-1
davidkpiano Jul 3, 2023
3a6eda6
Merge branch 'next' into v5/machine-types-1
davidkpiano Jul 4, 2023
29655d7
Merge branch 'next' into v5/machine-types-1
davidkpiano Jul 9, 2023
45d3ba0
Merge remote-tracking branch 'origin/next' into v5/machine-types-1
Andarist Jul 12, 2023
6da96cf
Tweak how `TActors` are passed around
Andarist Jul 14, 2023
fa4c398
Stick to the `.logic` prop
Andarist Jul 14, 2023
3fe8ec1
add some type tests for actor types
Andarist Jul 16, 2023
1ffb8e6
tweak things
Andarist Jul 16, 2023
d702291
Removed TActions from state
davidkpiano Jul 17, 2023
181c9df
Merge branch 'next' into v5/machine-types-1
davidkpiano Jul 19, 2023
30e628e
Fix Svelte type issues
davidkpiano Jul 25, 2023
a017d25
Merge remote-tracking branch 'origin/next' into v5/machine-types-1
Andarist Jul 26, 2023
08dc423
Add `TInput` to `TransitionActorLogic`
Andarist Jul 26, 2023
b946e4c
tweak small things
Andarist Jul 26, 2023
6860904
require actor IDs when they are configured
Andarist Jul 26, 2023
d377232
small tweaks
Andarist Jul 26, 2023
06927eb
Tweak changeset
Andarist Jul 26, 2023
7a16521
Tweak how actor type is distributed in `InvokeConfig`
Andarist Jul 26, 2023
b37fe82
disallow inline actors when the actor type is provided
Andarist Jul 26, 2023
2e2bdd6
Fix `GenerateActorEvents`
Andarist Jul 26, 2023
d5b63e3
Fixed `TInvokeSrcNameMap` usage in `GenerateActorEvents`
Andarist Jul 27, 2023
9861bed
fixed tests
Andarist Jul 27, 2023
ca81cc6
Add comments explaining `GenerateActorEvents`
Andarist Jul 27, 2023
819954e
fixed test
Andarist Jul 27, 2023
edbf505
remove old hack
Andarist Jul 27, 2023
041b40b
Compute `State['children']` more accurately
Andarist Jul 27, 2023
2e7a58b
fixed ComputeChildren type
Andarist Jul 27, 2023
76b3fb7
Add test and fix the children being a union
Andarist Jul 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .changeset/seven-balloons-attack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
'xstate': major
---

Actor types can now be specified in the `.types` property of `createMachine`:

```ts
const fetcher = fromPromise(() => fetchUser());

const machine = createMachine({
types: {} as {
actors: {
src: 'fetchData'; // src name (inline behaviors ideally inferred)
id: 'fetch1' | 'fetch2'; // possible ids (optional)
logic: typeof fetcher;
};
},
invoke: {
src: 'fetchData', // strongly typed
id: 'fetch2', // strongly typed
onDone: {
actions: ({ event }) => {
event.output; // strongly typed as { result: string }
}
},
input: { foo: 'hello' } // strongly typed
}
});
```
16 changes: 9 additions & 7 deletions packages/core/src/Machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import {
EventObject,
AnyEventObject,
MachineContext,
ActorMap,
InternalMachineImplementations,
ParameterizedObject
ParameterizedObject,
ProvidedActor
} from './types.ts';
import {
TypegenConstraint,
Expand All @@ -17,27 +17,29 @@ import { StateMachine } from './StateMachine.ts';
export function createMachine<
TContext extends MachineContext,
TEvent extends EventObject = AnyEventObject,
TActorMap extends ActorMap = ActorMap,
TActor extends ProvidedActor = ProvidedActor,
TTypesMeta extends TypegenConstraint = TypegenDisabled
>(
config: MachineConfig<
TContext,
TEvent,
ParameterizedObject,
TActorMap,
TActor,
TTypesMeta
>,
implementations?: InternalMachineImplementations<
TContext,
TEvent,
ResolveTypegenMeta<TTypesMeta, TEvent, ParameterizedObject, TActorMap>
ParameterizedObject,
TActor,
ResolveTypegenMeta<TTypesMeta, TEvent, ParameterizedObject, TActor>
>
): StateMachine<
TContext,
TEvent,
ParameterizedObject,
TActorMap,
ResolveTypegenMeta<TTypesMeta, TEvent, ParameterizedObject, TActorMap>
TActor,
ResolveTypegenMeta<TTypesMeta, TEvent, ParameterizedObject, TActor>
> {
return new StateMachine<any, any, any, any, any>(
config as any,
Expand Down
47 changes: 38 additions & 9 deletions packages/core/src/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
} from './stateUtils.ts';
import { TypegenDisabled, TypegenEnabled } from './typegenTypes.ts';
import type {
ActorRef,
ProvidedActor,
ActorRefFrom,
AnyState,
AnyStateMachine,
EventObject,
Expand All @@ -18,10 +19,36 @@ import type {
PersistedMachineState,
Prop,
StateConfig,
StateValue
StateValue,
TODO,
AnyActorRef,
Compute
} from './types.ts';
import { flatten, matchesState } from './utils.ts';

type ComputeConcreteChildren<TActor extends Required<ProvidedActor>> = {
[K in TActor['id']]?: ActorRefFrom<(TActor & { id: K })['logic']>;
};

type ComputeChildren<TActor extends ProvidedActor> =
string extends TActor['src']
? // TODO: replace with UnknownActorRef~
// TODO: consider adding `| undefined` here
Record<string, AnyActorRef>
: Compute<
// distribute over union
ComputeConcreteChildren<Extract<TActor, { id: string }>> &
// check if all actors have IDs
(undefined extends TActor['id']
? // if they don't we need to create an index signature containing all possible actor types
{
[id: string]: TActor extends any
? ActorRefFrom<TActor['logic']> | undefined
: never;
}
: {})
>;

export function isStateConfig<
TContext extends MachineContext,
TEvent extends EventObject
Expand All @@ -39,7 +66,8 @@ export function isStateConfig<
export const isState = isStateConfig;
export class State<
TContext extends MachineContext,
TEvent extends EventObject = EventObject,
TEvent extends EventObject,
TActor extends ProvidedActor,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this shouldn't receive TChildren already (preprocessed type). I'm still on the fence about this though

TResolvedTypesMeta = TypegenDisabled
> {
public tags: Set<string>;
Expand All @@ -63,7 +91,8 @@ export class State<
/**
* An object mapping actor names to spawned/invoked actors.
*/
public children: Record<string, ActorRef<any>>;
public children: ComputeChildren<TActor>;

/**
* Creates a new State instance for the given `stateValue` and `context`.
* @param stateValue
Expand All @@ -73,13 +102,13 @@ export class State<
TContext extends MachineContext,
TEvent extends EventObject = EventObject
>(
stateValue: State<TContext, TEvent, any> | StateValue,
stateValue: State<TContext, TEvent, TODO, any> | StateValue,
context: TContext = {} as TContext,
machine: AnyStateMachine
): State<TContext, TEvent, any> {
): State<TContext, TEvent, TODO, any> {
if (stateValue instanceof State) {
if (stateValue.context !== context) {
return new State<TContext, TEvent>(
return new State<TContext, TEvent, TODO, any>(
{
value: stateValue.value,
context,
Expand All @@ -98,7 +127,7 @@ export class State<
getStateNodes(machine.root, stateValue)
);

return new State<TContext, TEvent>(
return new State<TContext, TEvent, TODO, any>(
{
value: stateValue,
context,
Expand Down Expand Up @@ -127,7 +156,7 @@ export class State<
this.configuration =
config.configuration ??
Array.from(getConfiguration(getStateNodes(machine.root, config.value)));
this.children = config.children;
this.children = config.children as any;

this.value = getStateValue(machine.root, this.configuration);
this.tags = new Set(flatten(this.configuration.map((sn) => sn.tags)));
Expand Down
Loading