Skip to content

Instantly share code, notes, and snippets.

@ndvo
Created June 25, 2021 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ndvo/84733c1f3a58e381c62446961098a507 to your computer and use it in GitHub Desktop.
Save ndvo/84733c1f3a58e381c62446961098a507 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const type2scope = (type) => type.replace('SET', '').toLowerCase();
const setLocal = (ctx, ev) => {
const scope = type2scope(ev.type);
ctx.scope = scope;
ctx.country = ['country', 'region', 'local'].includes(scope);
ctx.region = ['region', 'local'].includes(scope);
ctx.city = ['local'].includes(scope);
};
const setIsLive = (ctx, ev) => {
const scope = type2scope(ev.type);
ctx.isLiveShow = ['union', 'country', 'region'].includes(scope);
};
const setProviders = (ctx, ev) => {
const eur = ['CHOOSEEUROPE', 'SETUNION'];
const eua = 'CHOOSEEUA';
const relevant = ['CHOOSEANY', ...eur, eua];
if (relevant.includes(ev.type)) {
ctx.providerValues = {
avalara: true,
onesource: true,
taxjar: [...eur, eua].includes(ev.type),
thomsonreuters: [...eur, eua].includes(ev.type),
};
}
};
const setProvider = (ctx, ev) => {
const providerMap = {
CHOOSETAXJAR: 'taxJar',
CHOOSETHOMSONREUTERS: 'thomsonReuters',
};
ctx.originShow = providerMap[ev.type] == 'thomsonReuters';
ctx.exemptShow = providerMap[ev.type] == 'thomsonReuters';
};
const setExempt = (ctx, ev) => {
ctx.exemptShow = ['SETTAXJAR', 'SETFOXY'].includes(ev.type);
};
const isLiveActions = [setProvider];
const scopeActions = [setIsLive, setLocal, setProviders];
const providerActions = [setExempt];
const scopeConfig = {
actions: scopeActions,
target: 'scope',
};
const isLiveConfig = {
actions: isLiveActions,
target: 'isLive',
};
const scopeStates = {
initial: 'scope',
states: {
scope: {
on: {
SETCOUNTRY: scopeConfig,
SETGLOBAL: scopeConfig,
SETLOCAL: scopeConfig,
SETREGION: scopeConfig,
SETUNION: scopeConfig,
},
},
},
};
const modeStates = {
initial: 'rate',
states: {
isLive: {
on: {
CHOOSEAVALARA: isLiveConfig,
CHOOSEONESOURCE: isLiveConfig,
CHOOSETAXJAR: isLiveConfig,
CHOOSETHOMSONREUTERS: isLiveConfig,
RATE: {
actions: [
...providerActions,
createAction('shipping', true),
createAction('provider', false),
],
target: 'rate',
},
},
},
rate: {
on: {
LIVE: {
actions: [createAction('shipping', false), createAction('provider', true)],
cond: (ctx) => ctx.isLiveShow,
target: 'isLive',
},
},
},
},
};
const countryStates = {
initial: 'any',
states: {
any: {
on: {
CHOOSEEUA: {
actions: setProviders,
cond: (ctx) => ctx.country,
target: 'northWest.euaCan',
},
CHOOSEEUROPE: {
actions: setProviders,
cond: (ctx) => ctx.country,
target: 'northWest.europe',
},
},
},
northWest: {
on: {
CHOOSEANY: {
actions: setProviders,
cond: (ctx) => ctx.country,
target: 'any',
},
},
states: {
euaCan: {
on: {
CHOOSEEUROPE: {
actions: setProviders,
cond: (ctx) => ctx.country,
target: 'europe',
},
},
},
europe: {
on: {
CHOOSEEUA: {
actions: setProviders,
cond: (ctx) => ctx.country,
target: 'euaCan',
},
},
},
},
},
},
};
const taxMachine = Machine({
context: {
city: false,
country: false,
exemptShow: false,
isLiveShow: false,
originShow: false,
provider: false,
providerValues: {
avalara: false,
onesource: false,
taxjar: false,
thomsonreuters: false,
},
region: false,
scope: 'global',
shipping: false,
},
id: 'taxMachine',
states: {
country: countryStates,
mode: modeStates,
scope: scopeStates,
},
type: 'parallel',
});
/**
* Create a simple action that sets a value to a context attribute.
*
* @param field to have the value set.
* @param value the value the field should assume.
* @returns function that changes the context.
*/
function createAction(field, value) {
return (ctx) => ctx[field] = value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment