Last active
November 4, 2020 14:55
-
-
Save sventschui/246efc1178263956ce501836f4a63a2e to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
This file contains 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 fetchInitialData = () => { | |
return Promise.resolve({ | |
countries: [], | |
allowedCurrencies: [] | |
}); | |
}; | |
const submitPayment = () => { | |
return Promise.resolve({}); | |
}; | |
const confirmPayment = () => { | |
return Promise.resolve({}); | |
}; | |
const initializeTransactionSigning = () => { | |
return Promise.resolve({}); | |
}; | |
const signTransaction = () => { | |
return Promise.resolve({}); | |
}; | |
const wasPaymentSubmitted = (context, event, meta) => { | |
console.log('wasPaymentSubmitted', { | |
context, | |
event, | |
meta | |
}); | |
return false; | |
}; | |
const requiresConfirmation = (context, event, meta) => { | |
console.log('requiresConfirmation', { | |
context, | |
event, | |
meta | |
}); | |
return false; | |
}; | |
const requiresTransactionSigning = (context, event, meta) => { | |
console.log('requiresTransactionSigning', { | |
context, | |
event, | |
meta | |
}); | |
return false; | |
}; | |
// TODO: use proper type from SVCs | |
const accountNoOrIbanChanged = (context, event, meta) => { | |
console.log('accountNoOrIbanChanged', { | |
context, | |
event, | |
meta | |
}); | |
return false; | |
}; | |
const isIbanValid = (context, event, meta) => { | |
console.log('isIbanValid', { | |
context, | |
event, | |
meta | |
}); | |
return false; | |
}; | |
const currencyChanged = (context, event, meta) => { | |
console.log('currencyChanged', { | |
context, | |
event, | |
meta | |
}); | |
return false; | |
}; | |
const costRuleChanged = (context, event, meta) => { | |
console.log('costRuleChanged', { | |
context, | |
event, | |
meta | |
}); | |
return false; | |
}; | |
const isSepaBank = (context, event, meta) => { | |
console.log('isSepaBank', { | |
context, | |
event, | |
meta | |
}); | |
return false; | |
}; | |
const sepaConditionsMet = (context, event, meta) => { | |
console.log('sepaConditionsMet', { | |
context, | |
event, | |
meta | |
}); | |
return false; | |
}; | |
const fetchBankInfoFromAccountNoOrIban = () => { | |
return Promise.resolve([]); | |
}; | |
const fetchBankInfoFromBic = () => { | |
return Promise.resolve([]); | |
}; | |
const paymentProcessMachine = Machine({ | |
id: 'paymentProcessHandler', | |
initial: 'initialize', | |
context: { | |
retries: 0 | |
}, | |
states: { | |
initialize: { | |
invoke: { | |
id: 'fetchInitialData', | |
src: fetchInitialData, | |
onDone: { | |
target: 'initialized', | |
actions: assign({ | |
countries: (ctx, e) => e.data.countries, | |
allowedCurrencies: (ctx, e) => e.data.allowedCurrencies | |
}) | |
}, | |
onError: 'initializationError' | |
} | |
}, | |
initializationError: { | |
on: { | |
RETRY_INIT: 'initialize' | |
} | |
}, | |
aborted: { | |
type: 'final' | |
}, | |
initialized: { | |
type: 'parallel', | |
states: { | |
sepa: { | |
initial: 'determineState', | |
on: { | |
'done.invoke.fetchBankInfoFromAccountNoOrIban': '.determineState', | |
'done.invoke.fetchBankInfoFromBic': '.determineState' | |
}, | |
states: { | |
determineState: { | |
always: [{ | |
target: 'sepaBank', | |
cond: isSepaBank | |
}, { | |
target: 'nonSepaBank' | |
}] | |
}, | |
sepaBank: { | |
initial: 'determineState', | |
on: { | |
'@form/change': [{ | |
target: '.determineState', | |
cond: currencyChanged | |
}, { | |
target: '.determineState', | |
cond: costRuleChanged | |
}] | |
}, | |
states: { | |
determineState: { | |
always: [{ | |
target: 'sepaConditionsMet', | |
cond: sepaConditionsMet | |
}, { | |
target: 'sepaConditionsNotMet' | |
}] | |
}, | |
sepaConditionsNotMet: {}, | |
sepaConditionsMet: {} | |
} | |
}, | |
nonSepaBank: {} | |
} | |
}, | |
bankInfo: { | |
initial: 'determineState', | |
on: { | |
'@form/change': [{ | |
target: '.determineState', | |
cond: accountNoOrIbanChanged | |
}] | |
}, | |
states: { | |
determineState: { | |
always: [{ | |
target: 'notSelectable', | |
cond: isIbanValid | |
}, { | |
target: 'selectable' | |
}] | |
}, | |
notSelectable: { | |
initial: 'loading', | |
invoke: { | |
id: 'fetchBankInfoFromAccountNoOrIban', | |
src: fetchBankInfoFromAccountNoOrIban, | |
onDone: '.success', | |
onError: '.error' | |
}, | |
states: { | |
loading: {}, | |
success: {}, | |
error: {} | |
} | |
}, | |
selectable: { | |
initial: 'loading', | |
invoke: { | |
id: 'fetchBankInfoFromBic', | |
src: fetchBankInfoFromBic, | |
onDone: '.success', | |
onError: '.error' | |
}, | |
states: { | |
loading: {}, | |
success: {}, | |
error: {} | |
} | |
} | |
} | |
}, | |
step: { | |
initial: 'userInput', | |
states: { | |
userInput: { | |
initial: 'idle', | |
states: { | |
idle: { | |
// @ts-expect-error { id: '<id>' } notation not known in TS... | |
on: { | |
CANCEL: { | |
id: 'aborted' | |
}, | |
SUBMIT: 'submitting' | |
} | |
}, | |
submitting: { | |
invoke: { | |
id: 'submitPayment', | |
src: submitPayment, | |
onDone: [{ | |
// @ts-expect-error { id: '<id>' } notation not known in TS... | |
id: 'initialized.step.paymentSubmitted', | |
cond: wasPaymentSubmitted | |
}, { | |
id: 'initialized.step.userConfirmation', | |
cond: requiresConfirmation | |
}, { | |
id: 'initialized.step.initializeTransactionSigning', | |
cond: requiresTransactionSigning | |
}, { | |
id: 'initialized.step.userInput' | |
}], | |
onError: { | |
id: 'initialized.step.userInput' | |
} // TODO: add submission error to the context | |
} | |
} | |
} | |
}, | |
userConfirmation: { | |
states: { | |
idle: { | |
// @ts-expect-error { id: '<id>' } notation not known in TS... | |
on: { | |
CONFIRM: 'confirming', | |
CHANGE: { | |
id: 'initialized.step.userInput' | |
}, | |
CANCEL: { | |
id: 'aborted' | |
} | |
} | |
}, | |
confirming: { | |
invoke: { | |
id: 'confirmPayment', | |
src: confirmPayment, | |
onDone: [{ | |
// @ts-expect-error { id: '<id>' } notation not known in TS... | |
id: 'initialized.step.paymentSubmitted', | |
cond: wasPaymentSubmitted | |
}, { | |
id: 'initialized.step.userConfirmation' | |
}], | |
onError: { | |
id: 'initialized.step.userConfirmation' | |
} // TODO: add confirmation error to the context | |
} | |
} | |
} | |
}, | |
transactionSigning: { | |
states: { | |
initializing: { | |
invoke: { | |
id: 'initializeTransactionSigning', | |
src: initializeTransactionSigning, | |
onDone: 'idle', | |
onError: 'error' | |
} | |
}, | |
error: { | |
on: { | |
RETRY_TRANSACTION_SIGNING: 'initializing' | |
} | |
}, | |
idle: { | |
// @ts-expect-error { id: '<id>' } notation not known in TS... | |
on: { | |
SUBMIT_TRANSACTION_SIGNING: 'signing', | |
CANCEL: { | |
id: 'aborted' | |
} | |
} | |
}, | |
signing: { | |
invoke: { | |
id: 'signTransaction', | |
src: signTransaction, | |
onDone: [{ | |
// @ts-expect-error { id: '<id>' } notation not known in TS... | |
id: 'initialized.step.paymentSubmitted', | |
cond: wasPaymentSubmitted | |
}, { | |
id: 'initialized.step.userConfirmation', | |
cond: requiresConfirmation | |
}, { | |
id: 'idle' | |
}], | |
onError: 'idle' // TODO: error state with a retry option? | |
} | |
} | |
} | |
}, | |
paymentSubmitted: { | |
type: 'final' | |
} | |
} | |
} | |
} | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment