Last active
September 16, 2019 09:06
-
-
Save amogower/55369c660b36cbd1d46fa7dcd739d384 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const singleBetMachine = Machine({ | |
| id: 'singleBet', | |
| initial: 'initial', | |
| context: { | |
| stake: '', | |
| }, | |
| states: { | |
| initial: {}, | |
| }, | |
| }); | |
| const multipleBetMachine = Machine({ | |
| id: 'multipleBet', | |
| initial: 'initial', | |
| context: { | |
| stake: '', | |
| }, | |
| states: { | |
| initial: {}, | |
| }, | |
| }); | |
| const betslipMachine = Machine({ | |
| id: 'ocBetslip', | |
| initial: 'hidden', | |
| context: { | |
| bookie: null, | |
| bookieList: [], | |
| errors: { | |
| global: [], | |
| multiple: [], | |
| single: [], | |
| total: 0, | |
| }, | |
| freeBets: [], | |
| multiples: [], | |
| market: {}, | |
| receiptNo: '', | |
| selectedBets: [ | |
| { betId: '1' }, | |
| { betId: '2' }, | |
| ], | |
| singles: [], | |
| totalStake: 0, | |
| totalReturns: 0, | |
| userSelectedBookie: false, | |
| }, | |
| states: { | |
| hidden: { | |
| id: 'hidden', | |
| on: { | |
| ADD_BET: { | |
| actions: 'addBet', | |
| target: 'visible', | |
| }, | |
| SHOW_BETSLIP: { | |
| target: 'visible', | |
| }, | |
| }, | |
| }, | |
| visible: { | |
| id: 'visible', | |
| initial: 'initializing', | |
| on: { | |
| HIDE_BETSLIP: { | |
| actions: 'hideBetslip', | |
| target: 'hidden', | |
| }, | |
| }, | |
| states: { | |
| initializing: { | |
| on: { | |
| '': [ | |
| { | |
| cond: 'hasNoBets', | |
| target: 'empty', | |
| }, | |
| { | |
| target: 'fetchingBetData', | |
| }, | |
| ] | |
| }, | |
| }, | |
| empty: { | |
| on: { | |
| ADD_BET: { | |
| actions: 'addBet', | |
| target: 'fetchingBetData', | |
| }, | |
| }, | |
| }, | |
| fetchingBetData: { | |
| invoke: { | |
| src: 'fetchBetData', | |
| onDone: { | |
| actions: 'addBets', | |
| target: 'initialized', | |
| }, | |
| onError: { | |
| target: 'error.global', | |
| }, | |
| }, | |
| }, | |
| initialized: { | |
| // entry: assign({ | |
| // multiples: (ctx) => ctx.multiples.map(multiple => ({ | |
| // ...multiple, | |
| // ref: spawn(multipleBetMachine.withContext(multiple)) | |
| // })), | |
| // singles: (ctx) => ctx.singles.map(single => ({ | |
| // ...single, | |
| // ref: spawn(singleBetMachine.withContext(single)) | |
| // })), | |
| // }), | |
| on: { | |
| '': [ | |
| { | |
| cond: 'noBookieSelected', | |
| target: 'bookieList', | |
| }, | |
| { | |
| target: 'betslip', | |
| } | |
| ], | |
| }, | |
| }, | |
| betslip: { | |
| on: { | |
| ADD_BET: { | |
| actions: 'addBet', | |
| target: 'fetchingBetData', | |
| }, | |
| CHANGE_STAKE: { | |
| actions: 'setStake', | |
| }, | |
| OPEN_BOOKIE_LIST: { | |
| target: 'bookieList', | |
| }, | |
| PLACE_BETSLIP: [ | |
| { | |
| cond: 'hasInsufficientFunds', | |
| target: 'error.global', | |
| }, | |
| { | |
| target: 'placingBetslip', | |
| }, | |
| ], | |
| REMOVE_BET: { | |
| actions: 'removeBet', | |
| }, | |
| TOGGLE_EACH_WAY: { | |
| actions: 'toggleEachWay', | |
| }, | |
| }, | |
| }, | |
| bookieList: { | |
| on: { | |
| CLOSE_BOOKIE_LIST: { | |
| target: 'initialized', | |
| }, | |
| SELECT_BOOKIE: { | |
| actions: 'selectBookie', | |
| target: 'initialized', | |
| }, | |
| }, | |
| }, | |
| placingBetslip: { | |
| invoke: { | |
| src: 'placeBetslip', | |
| onDone: { | |
| actions: 'cacheReceiptNo', | |
| target: 'receipt', | |
| }, | |
| onError: [ | |
| { | |
| cond: 'isNotSingleError', | |
| target: 'error.single', | |
| }, | |
| { | |
| cond: 'isNotMultipleError', | |
| target: 'error.multiple', | |
| }, | |
| { | |
| target: 'error.global', | |
| }, | |
| ], | |
| }, | |
| }, | |
| error: { | |
| initial: 'global', | |
| states: { | |
| global: { | |
| on: { | |
| CLOSE_MODAL: { | |
| target: '#visible.betslip', | |
| }, | |
| }, | |
| }, | |
| multiple: { | |
| on: { | |
| CHANGE_STAKE: { | |
| actions: 'setStake', | |
| target: '#visible.betslip', | |
| }, | |
| }, | |
| }, | |
| single: { | |
| on: { | |
| CHANGE_STAKE: { | |
| actions: 'setStake', | |
| target: '#visible.betslip', | |
| }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| receipt: { | |
| on: { | |
| DONE: { | |
| target: 'done', | |
| }, | |
| REUSE_SELECTIONS: { | |
| target: 'betslip', | |
| }, | |
| }, | |
| }, | |
| done: { | |
| type: 'final', | |
| }, | |
| }, | |
| }, | |
| }, | |
| onDone: { | |
| actions: 'hideBetslip', | |
| }, | |
| }, { | |
| actions: { | |
| addBets: assign({ | |
| multiples: (ctx, evt) => evt.data.multiples, | |
| singles: (ctx, evt) => evt.data.singles, | |
| }), | |
| cacheReceiptNo: assign({ | |
| receiptNo: (ctx, evt) => evt.receiptNo, | |
| }), | |
| hideBetslip: assign({ | |
| betslipVisible: false, | |
| }), | |
| removeBet: assign({ | |
| selectedBets: (ctx, evt) => ctx.selectedBets.filter((bet) => bet.betId !== evt.betId), | |
| singles: (ctx, evt) => ctx.singles.filter((single) => single.betId !== evt.betId), | |
| }), | |
| selectBookie: assign({ | |
| bookie: (ctx, evt) => evt.bookie, | |
| userSelectedBookie: (ctx, evt) => !!evt.bookie, | |
| }), | |
| setStake: assign({ | |
| singles: (ctx, evt) => ctx.singles.map((single) => { | |
| if (single.betId !== evt.betId) return single; | |
| return Object.assign({}, single, { | |
| stake: evt.value, | |
| }); | |
| }), | |
| }), | |
| showBetslip: assign({ | |
| betslipVisible: true, | |
| }), | |
| toggleEachWay: assign((ctx, evt) => { | |
| let key = 'singles'; | |
| let attrCheck = 'betId'; | |
| if (evt.betType !== 'Single') { | |
| key = 'multiples'; | |
| attrCheck = 'betType'; | |
| } | |
| return { | |
| [key]: ctx[key].map((bet) => { | |
| if (bet[attrCheck] !== evt[attrCheck]) return bet; | |
| return Object.assign({}, bet, { | |
| eachWay: !ctx.eachWay, | |
| }); | |
| }), | |
| }; | |
| }), | |
| }, | |
| guards: { | |
| hasInsufficientFunds: (ctx, evt) => { | |
| if (!ctx.bookie) return false; | |
| const hasFunds = | |
| Number(ctx.bookie.balance) >= Number(ctx.totalStake) || | |
| ctx.singles[0].freeBet; | |
| return !hasFunds; | |
| }, | |
| hasNoBets: (ctx) => !ctx.selectedBets.length, | |
| noBookieSelected: (ctx) => !ctx.bookie && !ctx.userSelectedBookie, | |
| isNotSingleError: () => false, | |
| isNotMultipleError: () => false, | |
| }, | |
| services: { | |
| fetchBetData: () => new Promise((resolve) => { | |
| setTimeout(() => { | |
| resolve({ | |
| multiples: [], | |
| singles: [ | |
| { betId: '1', eachWay: false }, | |
| { betId: '2', eachWay: true }, | |
| ], | |
| }); | |
| }, 1500); | |
| }), | |
| getCachedBets: () => new Promise((resolve) => { | |
| setTimeout(() => { | |
| resolve([1, 2]); | |
| }, 1500); | |
| }), | |
| }, | |
| }); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment