Skip to content

Instantly share code, notes, and snippets.

@simonedavico
Last active January 20, 2021 22:39
Show Gist options
  • Save simonedavico/b5554fe976ca748f6d0f4af998506c2a to your computer and use it in GitHub Desktop.
Save simonedavico/b5554fe976ca748f6d0f4af998506c2a to your computer and use it in GitHub Desktop.
Nested states for the payment authorisation state machine described in my blog post: https://medium.com/@sdavico/integrate-xstate-with-react-native-and-react-navigation-21ead87391da
import { Machine, send, assign, actions } from "xstate";
const { choose, log } = actions;
const keychainAccessStates = {
initial: "checkingBiometricFactor",
states: {
checkingBiometricFactor: {
on: {
RETRY: { target: "checkingBiometricFactor", internal: false },
STOP_TRYING: { target: "biometricAttemptsFinished" },
// prevent transitions from "checkingBiometricFactor"
KEYCHAIN_ACCESS_OK: undefined,
KEYCHAIN_ACCESS_KO: undefined,
},
invoke: {
id: "checkingBiometricFactor",
src: "checkingBiometricFactor",
onDone: {
target: "biometricSuccess",
},
onError: {
actions: [
assign((ctx) => ({
authAttempts: ctx.authAttempts + 1,
})),
choose([
{
cond: (ctx) => ctx.authAttempts > 3,
actions: [
log("attempts finished"),
send("STOP_TRYING"),
],
},
{
// else
actions: [log("retrying..."), send("RETRY")],
},
]),
],
},
},
},
biometricSuccess: {
type: "final",
entry: [
log("reporting ok to parent state"),
send("KEYCHAIN_ACCESS_OK")],
},
biometricAttemptsFinished: {
type: "final",
entry: [
log("reporting ko to parent state"),
send("KEYCHAIN_ACCESS_KO"),
],
},
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment