Skip to content

Instantly share code, notes, and snippets.

@JamieMason
Last active July 13, 2020 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamieMason/03abb84de0d2d0ab3cffd2bf6b04cc92 to your computer and use it in GitHub Desktop.
Save JamieMason/03abb84de0d2d0ab3cffd2bf6b04cc92 to your computer and use it in GitHub Desktop.
authMachine: Generated by XState Viz: https://xstate.js.org/viz
const loginMachine = Machine(
{
id: 'login',
initial: 'idle',
context: {
apiError: '',
email: '',
fieldError: '',
password: '',
shouldRememberMe: false,
},
states: {
idle: {
on: {
SET_EMAIL: {
actions: ['resetErrors', 'setEmail'],
},
SET_PASSWORD: {
actions: ['resetErrors', 'setPassword'],
},
SET_REMEMBER_ME: {
actions: 'setRememberMe',
target: 'idle',
},
SUBMIT: [
{
cond: 'hasInvalidFields',
actions: 'setFieldError',
},
{
target: 'submitForm',
},
],
},
},
submitForm: {
invoke: {
id: 'sendLogin',
src: 'sendLogin',
onError: {
actions: 'setApiError',
target: 'apiError',
},
onDone: {
entry: 'setRememberMeCookie',
target: 'complete',
},
},
},
apiError: {
type: 'final',
},
complete: {
type: 'final',
},
},
},
{
guards: {
hasInvalidFields: (ctx, event) => true,
},
actions: {
setApiError: assign({
apiError: (ctx, event) => event.data.msg,
}),
setFieldError: assign({
fieldError: (ctx, event) => 'Invalid Email Address',
}),
resetErrors: assign({
apiError: '',
fieldError: '',
}),
setEmail: assign({
apiError: '',
email: (ctx, event) => event.email,
fieldError: '',
}),
setPassword: assign({
apiError: '',
fieldError: '',
password: (ctx, event) => event.password,
}),
setRememberMe: assign({
shouldRememberMe: (ctx, event) => event.shouldRememberMe === true,
}),
},
services: {
sendLogin: apiThatOnlyWorksFor30SecondsEachMinute,
},
}
);
function apiThatOnlyWorksFor30SecondsEachMinute() {
return new Promise((resolve, reject) => {
setTimeout(() => {
new Date().getSeconds() < 30 ? resolve() : reject(new Error('500 Error'));
}, 2000);
});
}
const recoverPasswordMachine = Machine(
{
id: 'recoverPassword',
initial: 'idle',
context: {
apiError: '',
email: '',
fieldError: '',
},
states: {
idle: {
on: {
SET_EMAIL: {
actions: ['resetErrors', 'setEmail'],
},
SUBMIT: [
{
cond: 'hasInvalidFields',
actions: 'setFieldError',
},
{
target: 'submitForm',
},
],
},
},
submitForm: {
invoke: {
id: 'sendPasswordRecovery',
src: 'sendPasswordRecovery',
onError: {
actions: 'setApiError',
target: 'apiError',
},
onDone: {
target: 'complete',
},
},
},
apiError: {
type: 'final',
},
complete: {
type: 'final',
},
},
},
{
guards: {
hasInvalidFields: (ctx, event) => true,
},
actions: {
setApiError: assign({
apiError: (ctx, event) => event.data.msg,
}),
setFieldError: assign({
fieldError: (ctx, event) => 'Invalid Email Address',
}),
resetErrors: assign({
apiError: '',
fieldError: '',
}),
setEmail: assign({
email: (ctx, event) => event.email,
}),
},
services: {
sendRecoverEmail: apiThatOnlyWorksFor30SecondsEachMinute,
},
}
);
function apiThatOnlyWorksFor30SecondsEachMinute() {
return new Promise((resolve, reject) => {
setTimeout(() => {
new Date().getSeconds() < 30 ? resolve() : reject(new Error('500 Error'));
}, 2000);
});
}
const signupMachine = Machine(
{
id: 'signup',
initial: 'idle',
context: {
apiError: '',
confirmPassword: '',
email: '',
fieldError: '',
firstName: '',
lastName: '',
password: '',
shouldRememberMe: false,
},
states: {
idle: {
on: {
SET_CONFIRM_PASSWORD: {
actions: ['resetErrors', 'setConfirmPassword'],
},
SET_EMAIL: {
actions: ['resetErrors', 'setEmail'],
},
SET_FIRST_NAME: {
actions: ['resetErrors', 'setFirstName'],
},
SET_LAST_NAME: {
actions: ['resetErrors', 'setLastName'],
},
SET_PASSWORD: {
actions: ['resetErrors', 'setPassword'],
},
SET_REMEMBER_ME: {
actions: 'setRememberMe',
target: 'idle',
},
SUBMIT: [
{
cond: 'hasInvalidFields',
actions: 'setFieldError',
},
{
target: 'submitForm',
},
],
},
},
submitForm: {
invoke: {
id: 'sendSignup',
src: 'sendSignup',
onError: {
actions: 'setApiError',
target: 'apiError',
},
onDone: {
entry: 'setRememberMeCookie',
target: 'complete',
},
},
},
apiError: {
type: 'final',
},
complete: {
type: 'final',
},
},
},
{
guards: {
hasInvalidFields: (ctx, event) => true,
},
actions: {
setApiError: assign({
apiError: (ctx, event) => event.data.msg,
}),
setFieldError: assign({
fieldError: (ctx, event) => 'Invalid Email Address',
}),
resetErrors: assign({
apiError: '',
fieldError: '',
}),
setConfirmPassword: assign({
confirmPassword: (ctx, event) => event.email,
}),
setEmail: assign({
email: (ctx, event) => event.email,
}),
setFirstName: assign({
firstName: (ctx, event) => event.email,
}),
setLastName: assign({
lastName: (ctx, event) => event.email,
}),
setPassword: assign({
password: (ctx, event) => event.email,
}),
setRememberMe: assign({
shouldRememberMe: (ctx, event) => event.shouldRememberMe === true,
}),
setRememberMeCookie: (ctx) => {
if (ctx.shouldRememberMe === true) {
console.log('Set RememberMe Cookie to', ctx.email);
}
},
},
services: {
sendSignup: apiThatOnlyWorksFor30SecondsEachMinute,
},
}
);
function apiThatOnlyWorksFor30SecondsEachMinute() {
return new Promise((resolve, reject) => {
setTimeout(() => {
new Date().getSeconds() < 30 ? resolve() : reject(new Error('500 Error'));
}, 2000);
});
}
const authMachine = Machine({
id: 'auth',
initial: 'loggingIn',
states: {
loggingIn: {
invoke: {
src: loginMachine,
onDone: 'activeChildIsDone',
},
},
recoveringPassword: {
invoke: {
src: recoverPasswordMachine,
onDone: 'activeChildIsDone',
},
},
signingUp: {
invoke: {
src: signupMachine,
onDone: 'activeChildIsDone',
},
},
activeChildIsDone: {
type: 'final',
},
},
on: {
GO_LOGIN: 'loggingIn',
GO_RECOVER_PASSWORD: 'recoveringPassword',
GO_SIGN_UP: 'signingUp',
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment