xstate-codegen
xstate-codegen copied to clipboard
`createMachine` calls can only appear in the variable declaration or as a default export
Following the Reddit tutorial, there's a section that demonstrates splitting machines. In that section, they create a factory that creates a machine given a subreddit name. This is my translation to typescript
import { assign, createMachine } from "@xstate/compiled";
type SubredditContext = {
subreddit: string;
posts?: unknown[];
lastUpdated?: Date;
error?: string;
};
export type SubredditEvent = { type: "REFRESH" } | { type: "RETRY" };
export const createSubredditMachine = (subreddit: string) => {
return createMachine<SubredditContext, SubredditEvent, "subreddit">({
id: "subreddit",
initial: "loading",
context: {
subreddit,
posts: undefined,
lastUpdated: undefined,
error: undefined,
},
states: {
loading: {
invoke: {
id: "fetch-subreddit",
src: invokeFetchSubreddit,
onDone: {
target: "loaded",
actions: assign({
posts: (_, event) => event.data,
lastUpdated: (_) => new Date(),
}),
},
onError: "failure",
},
},
loaded: {
on: {
REFRESH: "loading",
},
},
failure: {
on: {
RETRY: "loading",
},
},
},
});
};
function invokeFetchSubreddit(context: SubredditContext) {
const { subreddit } = context;
return fetch(`https://www.reddit.com/r/${subreddit}.json`)
.then((res) => res.json())
.then((json) => json.data.children.map((child: any) => child.data));
}
As you may guess, xstate-codegen has an issue with it since we're not exporting the machine. The only thing that I can come up with is:
- extract the
createMachineoutside of the function and export it. - set
context.subredditas optional. - Change
createSubredditMachineto:
export const createSubredditMachine = (subreddit: string) => {
subredditMachine.withContext({ subreddit });
};
The only thing that bugs me is that I had to set the subreddit as optional. Is there a better way of handling this?
@Newbie012 Agree! The fact that we don't support factory machines is not exactly great, since they're a fantastic way to use XState.
@Andarist's PR will support this, though. Pretty much all the issues on the board are due to the Babel-based extraction mechanism, which #29 will replace entirely.