Skip to content

Instantly share code, notes, and snippets.

@drejohnson
Created January 1, 2021 01:18
Show Gist options
  • Save drejohnson/5688fd3737d410ff44680f6474c7c1dd to your computer and use it in GitHub Desktop.
Save drejohnson/5688fd3737d410ff44680f6474c7c1dd to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// Available variables:
// - Machine
// - interpret
// - assign
// - send
// - sendParent
// - spawn
// - raise
// - actions
// - XState (all XState exports)
// taken from https://www.w3resource.com/javascript/form/email-validation.php
const emailReg = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/;
// taken from https://stackoverflow.com/questions/19605150/regex-for-password-must-contain-at-least-eight-characters-at-least-one-number-a
const passwordReg = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/;
function mockAuthenticate(email, password, ms = 1500) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) resolve(email);
else reject("oopsy doopsy");
}, ms);
});
}
const initialContext = {
email: "",
password: ""
};
const authMachine = Machine({
id: "authentication",
initial: "loggedOut",
context: initialContext,
states: {
loggedOut: {
initial: "noErrors",
on: {
SIGN_UP: [
// check if everything is valid
{
target: ".invalidEmail",
cond: "checkEmail"
},
{
target: ".invalidPassword",
cond: "checkPassword"
},
// if all worked out, go ahead and authenticate
{
target: "authenticating",
actions: "saveData"
}
]
},
states: {
noErrors: {},
invalidEmail: {},
invalidPassword: {},
authFailed: {}
}
},
authenticating: {
invoke: {
id: "authenticateUser",
src: "authenticateUser",
onDone: {
target: "loggedIn",
actions: "clearSignUp"
},
onError: {
target: "loggedOut.authFailed"
}
}
},
loggedIn: {
on: {
LOGOUT: "loggedOut"
}
}
}
},
{
actions: {
clearSignUp: assign(initialContext),
saveData: assign({
email: (_, e) => e.email,
password: (_, e) => e.password
})
},
guards: {
checkEmail: (_, e) => !emailReg.test(e.email),
checkPassword: (_, e) => !passwordReg.test(e.password)
},
services: {
authenticateUser: ctx => {
const { email, password } = ctx;
return mockAuthenticate(email, password);
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment