Skip to content

Instantly share code, notes, and snippets.

@sesteva
Last active December 18, 2019 14:43
Show Gist options
  • Save sesteva/80c04cf62ab99ffb7c720c804017ba04 to your computer and use it in GitHub Desktop.
Save sesteva/80c04cf62ab99ffb7c720c804017ba04 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const cartActions = {
addProduct: assign((ctx, evt)=> ({
cart:{
...ctx.cart,
count: ctx.cart.count + 1,
products: [...ctx.cart.products, evt.payload]
}
})),
addSaveForLater: assign((ctx, evt)=>({
savedForLater:{
...ctx.savedForLater,
count: ctx.savedForLater.count + 1,
products: [...ctx.savedForLater.products, evt.payload]
}
})),
removeProduct: assign((ctx, evt)=> ({
cart:{
...ctx.cart,
count: ctx.cart.count - 1,
products: ctx.cart.products.filter(p => {
if(p.id === evt.payload.id){
return false
}
return true
})
}
})),
unsaveProduct: assign((ctx, evt)=> ({
savedForLater:{
...ctx.savedForLater,
count: ctx.savedForLater.count - 1,
products: ctx.savedForLater.products.filter(p => {
if(p.id === evt.payload.id){
return false
}
return true
})
}
})),
updateProduct: assign((ctx, evt) => ({
cart:{
...ctx.cart,
products: ctx.cart.products.map( p => {
if(p.id === evt.payload.id){
return {
...p,
...evt.payload
}
}
return p
})
}
})),
saveForLater: send((context, event) => ({
type: 'ADD_TO_LIST',
payload: event.payload
})),
moveToCart: send((context, event) => ({
type: 'ADD',
payload: event.payload
}))
}
//this is how to unit test these ations
// console.log(cartActions.increment.assignment({count:100}, {"type":"ADD"}))
const cartGuards= {
isCartEmpty: (ctx, evt) => ctx.cart.count < 1,
isSavedEmpty: (ctx, evt) => ctx.savedForLater.count < 1,
isProduct: (ctx, evt) => {
const p = evt.payload
return p && p.id && p.id.length > 0 // add more validations
}
}
const cartmachine = Machine({
id: 'cartMachine',
initial: 'empty',
context: {
cart: {
count: 0,
products: [],
subtotal:0,
delivery:0,
estimatedTaxesAndFees:0,
estimatedTotal:0,
error: undefined
},
savedForLater: {
count: 0,
products: [],
}
},
type: 'parallel',
states: {
cart: {
id: 'cart',
initial: 'empty',
states: {
empty: {
on: {
ADD: {
target: 'unpaid',
actions: ['addProduct'],
cond: 'isProduct'
},
}
},
unpaid:{
initial:'normal',
on: {
'': {
target: 'empty',
cond: 'isCartEmpty'
},
SAVE_FOR_LATER: {
actions: ['saveForLater', 'removeProduct']
},
REMOVE: {
target: '.normal',
actions: 'removeProduct',
cond: 'isProduct'
},
ADD: {
target: '.normal',
actions: 'addProduct',
cond: 'isProduct'
},
UPDATE_QTY: {
target: '.normal',
actions: 'updateProduct',
cond: 'isProduct'
},
UPDATE_PRICE: {
target: '.normal',
actions: 'updateProduct',
cond: 'isProduct'
},
PAY: 'paying'
},
states: {
error: {},
normal: {}
}
},
paying:{
on: {
RESOLVE: 'paid',
REJECT: 'unpaid.error'
}
},
paid: {
after: {
1000: 'empty'
}
}
}
},
savedForLater:{
id: 'savedForLater',
initial: 'empty',
on: {
ADD_TO_LIST: {
target:'.saved',
actions: 'addSaveForLater'
},
},
states:{
empty:{},
saved:{
on: {
'':
{
target: 'empty',
cond: 'isSavedEmpty'
}
,
UNSAVE: '',
MOVE_TO_CART: {
actions: ['moveToCart', 'unsaveProduct']
}
}
}
}
}
}
},{
actions: cartActions,
guards: cartGuards
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment