Skip to content

Instantly share code, notes, and snippets.

@junhuif
Last active April 17, 2020 02:11
Show Gist options
  • Save junhuif/be0b1929d7ce0fd0fcb3dcf749227a24 to your computer and use it in GitHub Desktop.
Save junhuif/be0b1929d7ce0fd0fcb3dcf749227a24 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 = 500;
const MAX_FETCH_COUNT = 3;
const ERROR_ORDER_CODE_IS_UNDEFINED = new Error("orderCode is undefined");
const ERROR_FETCH_TIMES_OVER_LIMITS = new Error(
"fetch order times over limits"
);
// helpers
function orderCodeIsUndefined(context) {
return !(context.order != null && context.order.orderCode != null);
}
function orderNumberIsDefined(context, event) {
return (
event.data?.isPaid === true && event.data?.order?.displayOrderNumber != null
);
}
function fetchCountIsOverLimited(context) {
return context.fetchCount >= MAX_FETCH_COUNT;
}
const processingStates = {
key: "processing",
type: "compound",
initial: "waiting",
states: {
waiting: {
after: {
[FETCH_INTERVAL]: "fetching",
},
},
fetching: {
on: {
"": [
{
target: "error",
actions: [
assign({
error: (_context, _event) => ERROR_ORDER_CODE_IS_UNDEFINED,
}),
],
cond: orderCodeIsUndefined,
},
],
},
invoke: {
id: "fetchOrder",
src: SERVICE_ORDER_FETCHER,
onDone: [
{
target: "processed",
actions: assign({
output: (_context, event) => event.data,
fetchCount: (context) => context.fetchCount + 1,
}),
cond: orderNumberIsDefined,
},
{
target: "error",
actions: [
assign({
error: (_context, _event) => ERROR_FETCH_TIMES_OVER_LIMITS,
}),
],
cond: fetchCountIsOverLimited,
},
{
target: "waiting",
actions: assign({
output: (_context, event) => event.data,
fetchCount: (context) => context.fetchCount + 1,
}),
},
],
onError: {
target: "error",
actions: assign({
error: (_context, event) => event.data,
fetchCount: (context) => context.fetchCount + 1,
}),
},
},
},
processed: {
type: "final",
},
error: {
type: "final",
},
},
};
// XState Visualizer:
// https://xstate.js.org/viz/?gist=da25f3d2d9ad77791d06165ff1ea1d61
const orderReferenceDetailsMachine = Machine({
id: "orderReferenceDetails",
initial: "processing",
context: {
fetchCount: 0,
order: { orderCode: "<order code>" }, // empty order
},
states: {
processing: {
...processingStates,
on: {
"": [
{
target: "done",
in: "#orderReferenceDetails.processing.processed",
},
{
target: "error",
in: "#orderReferenceDetails.processing.error",
},
],
},
},
done: {
entry: assign({
order: (context, _event) => context.output?.order || context.order,
}),
type: "final",
},
error: {
on: {
RETRY: {
target: "processing",
actions: assign({
fetchCount: (_context, _event) => 0,
}),
},
},
},
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment