Skip to content

Instantly share code, notes, and snippets.

@DaveHudson
Last active July 27, 2020 13:47
Show Gist options
  • Save DaveHudson/d99b1b43efd656b4cf5b49a69804f6bd to your computer and use it in GitHub Desktop.
Save DaveHudson/d99b1b43efd656b4cf5b49a69804f6bd 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)
const cartStates = {
id: 'cart',
initial: 'emptyCart',
context: {
cart: {
items: [],
cartTotal: 0,
shipping: 0,
tax: 0,
orderTotal: 0,
},
},
states: {
emptyCart: {
on: {
ADDITEM: 'addToCart',
},
},
cart: {
on: {
ADDITEM: 'addToCart',
REMOVEITEM: 'removeFromCart',
INCREMENTITEM: 'incrementItem',
DECREMENTITEM: 'decrementItem',
CHECKOUT: '#delivery',
},
},
addToCart: {
invoke: {
src: 'addItemToCart',
onDone: {
target: 'cart',
actions: ['setContext'],
},
onError: 'error',
},
},
removeFromCart: {
invoke: {
src: 'removeItemFromCart',
onDone: {
target: 'isCartEmpty',
actions: ['setContext'],
},
onError: 'error',
},
},
incrementItem: {
invoke: {
src: 'incrementItemInCart',
onDone: {
target: 'cart',
actions: ['setContext'],
},
onError: 'error',
},
},
decrementItem: {
invoke: {
src: 'decrementItemInCart',
onDone: {
target: 'cart',
actions: ['setContext'],
},
onError: 'error',
},
},
checkout: {
on: {
'': [{ target: '#checkout.delivery' }],
},
},
isCartEmpty: {
on: {
'': [
{ target: 'cart', cond: 'cartValid' },
{ target: 'emptyCart', cond: 'cartInvalid' },
],
},
},
error: {},
},
};
const deliveryStates = {
id: 'delivery',
initial: 'addresses',
states: {
addresses: {
initial: 'isCartValid',
states: {
isCartValid: {
on: {
'': [
{ target: 'fetchAddresses', cond: 'cartValid' },
{ target: '#delivery.error', cond: 'cartInvalid' },
],
},
},
fetchAddresses: {
invoke: {
src: 'fetchAddresses',
onDone: {
target: 'addressList',
actions: ['setContextAddresses'],
},
onError: {
target: '#delivery.error',
},
},
},
addressList: {
on: {
ADD: '#delivery.addAddress',
UPDATE: '#delivery.updateAddress',
DELETE: '#delivery.deleteAddress',
SELECT: '#checkout.shipping',
},
},
},
},
addAddress: {
initial: 'form',
states: {
form: {
on: {
SUBMIT: 'saveAddress',
},
},
saveAddress: {
invoke: {
src: 'saveAddressAPI',
onDone: {
target: '#delivery.addresses',
},
onError: {
target: '#delivery.error',
},
},
},
},
},
updateAddress: {
initial: 'fetchAddress',
states: {
fetchAddress: {
invoke: {
src: 'fetchAddress',
onDone: {
target: 'form'
},
onError: {
target: '#delivery.error'
}
}
},
form: {
on: {
SUBMIT: 'updateAddress',
},
},
updateAddress: {
invoke: {
src: 'updateAddress',
onDone: {
target: '#delivery.addresses',
},
onError: {
target: '#delivery.error',
},
},
},
},
},
deleteAddress: {
initial: 'form',
states: {
form: {
on: {
SUBMIT: 'deleteAddress',
},
},
deleteAddress: {
invoke: {
src: 'deleteAddress',
onDone: {
target: '#delivery.addresses',
},
onError: {
target: '#delivery.error',
},
},
},
},
},
error: {},
},
};
const shippingStates = {
id: 'shipping',
initial: 'isCartValid',
states: {
isCartValid: {
on: {
'': [
{ target: 'getRates', cond: 'cartValidAndAddress' },
{ target: '#shipping.error', cond: 'cartInvalidAndAddress' },
],
},
},
getRates: {
invoke: {
src: 'fetchShippingRates',
onDone: {
target: 'shippingRates',
},
onError: {
target: 'error',
},
},
},
shippingRates: {
on: {
SELECT: '#checkout.payment',
},
},
error: {
on: {
RETRY: 'getRates',
},
},
},
};
const paymentStates = {
id: 'payment',
initial: 'isCartValid',
states: {
isCartValid: {
on: {
'': [
{ target: 'paymentForm', cond: 'cartValidShipping' },
{ target: '#payment.error', cond: 'cartInvalidShipping' },
],
},
},
paymentForm: {
on: {
SUBMIT: 'paymentRequest',
},
},
paymentRequest: {
invoke: {
src: 'postPaymentRequest',
onDone: {
target: 'resetCart',
},
onError: {
target: 'error',
},
},
},
resetCart: {
invoke: {
src: 'resetCart',
onDone: {
target: '#checkout.success'
},
onError: {
target: 'error'
}
}
},
error: {},
},
};
const checkoutMachine = Machine({
id: 'checkout',
initial: 'cart',
context: {},
states: {
cart: {
...cartStates
},
delivery: {
...deliveryStates
},
shipping: {
...shippingStates
},
payment: {
...paymentStates
},
success: {
type: 'final'
}
}
},
{
guards: {
cartValid: (context) => {
return true;
},
cartInvalid: (context) => {
return false;
},
cartValidAndAddress: (context) => {
return true;
},
cartInvalidAndAddress: (context) => {
return false;
},
cartValidShipping: (context) => {
return true;
},
cartInvalidShipping: (context) => {
return false;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment