Skip to content

Instantly share code, notes, and snippets.

@mattpocock
Created July 30, 2020 10:49
Show Gist options
  • Save mattpocock/6dceeecd92e00e8af8cfebc157bb6ffd to your computer and use it in GitHub Desktop.
Save mattpocock/6dceeecd92e00e8af8cfebc157bb6ffd to your computer and use it in GitHub Desktop.
import { useMachine } from '@xstate/react';
import {
StateMachine,
AnyEventObject,
EventObject,
State,
Interpreter,
ActionObject,
ActionFunction,
} from 'xstate';
export type AddUserMachineStateMatches =
| 'idle'
| 'updating'
| 'updating.checking'
| 'updating.updatingUserAccount'
| 'updating.updatingUserEntity'
| 'updating.complete'
| 'creating'
| 'creating.creatingUserInCognito'
| 'creating.complete'
| 'creating.errored'
| 'complete';
export interface AddUserMachineOptions<
Context = any,
Event extends EventObject = AnyEventObject
> {
context?: Partial<Context>;
guards: {
hasChangedWhetherUserIsAdmin: (context: Context) => boolean;
};
actions: {
goBackToUsersPage:
| ActionObject<Context, Extract<Event, { type: 'CANCEL' }>>
| ActionFunction<Context, Extract<Event, { type: 'CANCEL' }>>;
reportUpdateSuccessViaToast:
| ActionObject<
Context,
Extract<Event, { type: 'done.state.addUserMachine.updating' }>
>
| ActionFunction<
Context,
Extract<Event, { type: 'done.state.addUserMachine.updating' }>
>;
reportErrorViaToast:
| ActionObject<
Context,
Extract<
Event,
| { type: 'error.platform.updateUserAccount' }
| { type: 'error.platform.updateUser' }
>
>
| ActionFunction<
Context,
Extract<
Event,
| { type: 'error.platform.updateUserAccount' }
| { type: 'error.platform.updateUser' }
>
>;
reportCreateSuccessViaToast:
| ActionObject<Context, Event>
| ActionFunction<Context, Event>;
};
services: {
updateUserAccount: (
context: Context,
) => Promise<
Extract<Event, { type: 'done.invoke.updateUserAccount' }> extends {
data: infer T;
}
? T
: any
>;
updateUser: (
context: Context,
) => Promise<
Extract<Event, { type: 'done.invoke.updateUser' }> extends {
data: infer T;
}
? T
: any
>;
createUserInCognito: (
context: Context,
) => Promise<
Extract<Event, { type: 'done.invoke.createUserInCognito' }> extends {
data: infer T;
}
? T
: any
>;
};
devTools?: boolean;
}
export type AddUserMachineState<Context, Event extends EventObject> = Omit<
State<Context, Event>,
'matches'
> & {
matches: (match: AddUserMachineStateMatches) => boolean;
};
export const useAddUserMachine = <
Context = any,
StateSchema = any,
Event extends EventObject = AnyEventObject
>(
machine: StateMachine<Context, StateSchema, Event>,
options: AddUserMachineOptions<Context, Event>,
): [
AddUserMachineState<Context, Event>,
Interpreter<Context, StateSchema, Event>['send'],
Interpreter<Context, StateSchema, Event>,
] => {
return useMachine(machine as any, options as any) as any;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment