Skip to content

Instantly share code, notes, and snippets.

@junhuif
Last active April 15, 2020 10:50
Show Gist options
  • Save junhuif/da25f3d2d9ad77791d06165ff1ea1d61 to your computer and use it in GitHub Desktop.
Save junhuif/da25f3d2d9ad77791d06165ff1ea1d61 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const SERVICE_ORDER_FETCHER = "orderFetcher";
const STATE_COMPLETED = "completed";
const STATE_FAILED = "failed";
const FETCH_INTERVAL = 1000;
const MAX_FETCH_COUNT = 60;
const ERROR_ORDER_CODE_IS_UNDEFINED = new Error("orderCode is undefined");
const ERROR_FETCH_TIMES_OVER_LIMITS = new Error(
"fetch order times over limits"
);
// XState Visualizer:
// https://xstate.js.org/viz/?gist=da25f3d2d9ad77791d06165ff1ea1d61
const orderReferenceDetailsMachine = Machine({
id: "orderReferenceDetails",
initial: "idle",
context: {
order: { orderCode: '<order code>' }, // empty order
},
states: {
idle: {
on: {
"": [
{ target: "fetching", cond: canFetch },
{
target: [STATE_FAILED],
actions: [
assign({
error: (_context, _event) => ERROR_ORDER_CODE_IS_UNDEFINED,
}),
],
},
],
},
},
fetching: {
invoke: {
id: "fetchOrder",
src: SERVICE_ORDER_FETCHER,
onDone: {
target: "fetched",
actions: assign({
output: (_context, event) => event.data,
fetchCount: (context) => {
if (context.fetchCount != null) {
return context.fetchCount + 1;
}
return 1;
},
}),
},
onError: {
target: [STATE_FAILED],
actions: assign({ error: (_context, event) => event.data }),
},
},
},
fetched: {
on: {
"": [
{ target: STATE_COMPLETED, cond: orderNumberIsDefined },
{
target: STATE_FAILED,
cond: fetchCountIsOverLimited,
actions: [
assign({
error: (_context, _event) => ERROR_FETCH_TIMES_OVER_LIMITS,
}),
],
},
],
},
after: {
[FETCH_INTERVAL]: "fetching",
},
},
[STATE_COMPLETED]: {
entry: assign({
order: (context, _event) => context.output?.order || context.order,
}),
type: "final",
},
[STATE_FAILED]: {
type: "final",
},
},
});
// helpers
function canFetch(context) {
return isOrderValid(context);
}
function isOrderValid(context) {
return context.order != null && context.order.orderCode != null;
}
function orderNumberIsDefined(context) {
return (
context.output?.isPaid === true &&
context.output?.order?.displayOrderNumber != null
);
}
function fetchCountIsOverLimited(context) {
return context.fetchCount != null && context.fetchCount > MAX_FETCH_COUNT;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment