Created
August 5, 2021 11:23
-
-
Save DGollings/5305d5a540c95a3e52fdee2ada969c1d 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
// Available variables: | |
// - Machine | |
// - interpret | |
// - assign | |
// - send | |
// - sendParent | |
// - spawn | |
// - raise | |
// - actions | |
// - XState (all XState exports) | |
const fetchMachine = Machine( { | |
id: "ParcelStates", | |
context: { | |
timestamp: 0, | |
parcelID: "", | |
isPickup: false, | |
isPlanned: false, | |
comment: "", | |
updatingQuantity: false, | |
verifiedQuantity: false, | |
quantityExpected: 0, | |
quantityActual: -1, | |
errorMessage: "", | |
}, | |
initial: "created", | |
states: { | |
created: { | |
always: [ | |
{ target: "pending_planning_pickup", cond: "isPickup" }, | |
{ target: "pending_planning_delivery", cond: "isDelivery" }, | |
], | |
exit: ["updateTimestamp"], | |
}, | |
pending_planning_pickup: { | |
meta: { | |
label: "Pending planning pickup", | |
error: false, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_IS_PLANNED_TRUE: { | |
actions: [ | |
assign({ | |
isPlanned: context => (context.isPlanned = true), | |
}), | |
], | |
target: "planned_for_pickup", | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
pending_planning_delivery: { | |
meta: { | |
label: "Pending planning delivery", | |
error: false, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_IS_PLANNED_TRUE: { | |
actions: "setPlanned", | |
target: "planned_for_delivery", | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
planned_for_delivery: { | |
meta: { | |
label: "Planned for delivery", | |
error: false, | |
completed: false, | |
} , | |
on: { | |
LOAD_VEHICLE: "verify_quantity", | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_IS_PLANNED_FALSE: { | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
planned_for_pickup: { | |
meta: { | |
label: "Planned for pickup", | |
error: false, | |
completed: false, | |
} , | |
on: { | |
PICKING_UP: "picking_up", | |
PRIVATE_IS_PLANNED_FALSE: { | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
picking_up: { | |
meta: { | |
label: "Picking up", | |
error: false, | |
completed: false, | |
} , | |
on: { | |
VERIFY_QUANTITY: "verify_quantity", | |
WRONG_ADDRESS: "wrong_address", | |
ADDRESS_NOT_FOUND: "address_not_found", | |
ERROR_OTHER: "exception_other", | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: "planned_for_pickup", | |
}, | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
verify_quantity: { | |
meta: { | |
label: "Verify quantity", | |
overrideLabel: "Verified quantity", | |
error: false, | |
completed: false, | |
} , | |
entry: "updatingQuantityTrue", | |
on: { | |
VERIFIED_QUANTITY: [ | |
{ | |
target: "ready_for_departure", | |
actions: "setQuantity", | |
cond: "checkQuantityValueDelivery", | |
}, | |
{ | |
target: "picked_up", | |
actions: "setQuantity", | |
cond: "checkQuantityValuePickup", | |
}, | |
], | |
PARCEL_TOO_LARGE: "parcel_too_large", | |
PARCEL_TOO_HEAVY: "parcel_too_heavy", | |
PARCEL_MISSING: "parcel_missing", | |
PARCEL_DAMAGED_ALREADY: "parcel_damaged_already", | |
PARCEL_COULD_NOT_BE_PICKED_UP: "parcel_could_not_be_picked_up", | |
PRIVATE_UPDATE_QUANTITY: { | |
actions: "setQuantity", | |
cond: "checkQuantityValue", | |
}, | |
PRIVATE_BACK: [ | |
{ target: "ready_for_departure", cond: "isDelivery" }, | |
{ target: "picking_up", cond: "isPickup" }, | |
], | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: [ | |
"updatingQuantityFalse", | |
"verifiedQuantityTrue", | |
"updateTimestamp", | |
], | |
}, | |
picked_up: { | |
meta: { | |
label: "Picked up", | |
error: false, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
DELIVERED_TO_HUB: { | |
target: "delivered_to_hub", | |
}, | |
IN_TRANSIT: { | |
target: "in_transit", | |
}, | |
PRIVATE_BACK: { | |
target: "verify_quantity", | |
}, | |
OVERRIDE_LABEL_ADJUST_QUANTITY: { | |
target: "verify_quantity", | |
}, | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
delivered_to_hub: { | |
meta: { | |
label: "Delivered to hub", | |
error: false, | |
completed: true, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["picked_up"], | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
ready_for_departure: { | |
meta: { | |
label: "Ready for departure", | |
error: false, | |
completed: false, | |
} , | |
on: { | |
DEPART: { | |
target: "in_transit", | |
}, | |
OVERRIDE_LABEL_ADJUST_QUANTITY: { | |
target: "verify_quantity", | |
}, | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
in_transit: { | |
meta: { | |
label: "In transit", | |
error: false, | |
completed: false, | |
} , | |
on: { | |
AT_DELIVERY_LOCATION: "at_delivery_location", | |
PARCEL_LOST: "parcel_lost", | |
PARCEL_DAMAGED_IN_TRANSIT: "parcel_damaged_in_transit", | |
WRONG_ADDRESS: "wrong_address", | |
ADDRESS_NOT_FOUND: "address_not_found", | |
ERROR_OTHER: "exception_other", | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: [ | |
{ target: "ready_for_departure", cond: "isDelivery" }, | |
{ target: "picked_up", cond: "isPickup" }, | |
], | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
at_delivery_location: { | |
meta: { | |
label: "At delivery location", | |
error: false, | |
completed: false, | |
} , | |
on: { | |
ADDRESSEE: "delivered", | |
NEIGHBOURS: "delivered_neighbours", | |
COLLECTION_POINT: "delivered_collection_point", | |
DELIVERY_REFUSED: "delivery_refused", | |
ERROR_OTHER: "exception_other", | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["in_transit"], | |
}, | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
delivered: { | |
meta: { | |
label: "Delivered", | |
error: false, | |
completed: true, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["at_delivery_location"], | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
delivered_neighbours: { | |
meta: { | |
label: "Delivered neighbours", | |
error: false, | |
completed: true, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["at_delivery_location"], | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
delivered_collection_point: { | |
meta: { | |
label: "Delivered collection point", | |
error: false, | |
completed: true, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["at_delivery_location"], | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
parcel_missing: { | |
meta: { | |
label: "Parcel missing", | |
error: true, | |
completed: true, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["verify_quantity"], | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
parcel_damaged_already: { | |
meta: { | |
label: "Parcel damaged already", | |
error: true, | |
completed: true, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["verify_quantity"], | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
parcel_could_not_be_picked_up: { | |
meta: { | |
label: "Parcel could not be picked up", | |
error: true, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["verify_quantity"], | |
}, | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
wrong_address: { | |
meta: { | |
label: "Wrong address", | |
error: true, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: [ | |
{ target: "in_transit", cond: "isDelivery" }, | |
{ target: "picking_up", cond: "isPickup" }, | |
], | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
address_not_found: { | |
meta: { | |
label: "Address not found", | |
error: true, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: [ | |
{ target: "in_transit", cond: "isDelivery" }, | |
{ target: "picking_up", cond: "isPickup" }, | |
], | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
parcel_lost: { | |
meta: { | |
label: "Parcel lost", | |
error: true, | |
completed: true, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["in_transit"], | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
parcel_damaged_in_transit: { | |
meta: { | |
label: "Parcel damaged in transit", | |
error: true, | |
completed: true, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["in_transit"], | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
parcel_too_large: { | |
meta: { | |
label: "Parcel too large", | |
error: true, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
OVERRIDE_LABEL_ADJUST_QUANTITY: { | |
target: "verify_quantity", | |
}, | |
PRIVATE_BACK: { | |
target: "verify_quantity", | |
}, | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
parcel_too_heavy: { | |
meta: { | |
label: "Parcel too heavy", | |
error: true, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
OVERRIDE_LABEL_ADJUST_QUANTITY: { | |
target: "verify_quantity", | |
}, | |
PRIVATE_BACK: { | |
target: "verify_quantity", | |
}, | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
delivery_refused: { | |
meta: { | |
label: "Delivery refused", | |
error: true, | |
completed: true, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: ["at_delivery_location"], | |
}, | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
delivery_failed: { | |
meta: { | |
label: "Delivery failed", | |
error: true, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: { | |
target: "verify_quantity", | |
}, | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
exception_other: { | |
meta: { | |
label: "Unknown error", | |
error: true, | |
completed: false, | |
} , | |
on: { | |
PRIVATE_SAVE_COMMENT: { | |
actions: ["setCommentField"], | |
}, | |
PRIVATE_BACK: [ | |
{ target: "in_transit", cond: "isDelivery" }, | |
{ target: "picking_up", cond: "isPickup" }, | |
], | |
PRIVATE_IS_PLANNED_FALSE: [ | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_delivery", | |
cond: "isDelivery", | |
}, | |
{ | |
actions: "setNotPlanned", | |
target: "pending_planning_pickup", | |
cond: "isPickup", | |
}, | |
], | |
}, | |
exit: ["updateTimestamp"], | |
}, | |
restart: { | |
always: [ | |
{ | |
actions: ["resetContext"], | |
target: "created", | |
}, | |
], | |
exit: ["updateTimestamp"], | |
}, | |
}, | |
on: { | |
FORCE_PICKED_UP: { | |
target: "picked_up", | |
}, | |
FORCE_PARCEL_COULD_NOT_BE_PICKED_UP: { | |
target: "parcel_could_not_be_picked_up", | |
}, | |
FORCE_IN_TRANSIT: { | |
target: "in_transit", | |
}, | |
FORCE_ADDRESSEE: { | |
target: "delivered", | |
}, | |
FORCE_NEIGHBOURS: { | |
target: "delivered_neighbours", | |
}, | |
FORCE_DELIVERY_REFUSED: { | |
target: "delivery_refused", | |
}, | |
FORCE_DELIVERY_FAILED: { | |
target: "delivery_failed", | |
}, | |
}, | |
}, | |
{ | |
guards: { | |
isPickup: context => context.isPickup === true, | |
isDelivery: context => context.isPickup === false, | |
isPlannedForDelivery: context => | |
context.isPlanned === true && context.isPickup === false, | |
isPlannedForPickup: context => | |
context.isPlanned === true && context.isPickup === true, | |
checkQuantityValue: (context, event) => { | |
event = event ; | |
switch (event.input_type) { | |
case "text": | |
if (!event.value) { | |
console.log("EVENT VALUE", event.value); | |
context.errorMessage = "value is not a number"; | |
return false; | |
} | |
break; | |
case "number": { | |
const value = Number(event.value); | |
if (isNaN(value)) { | |
context.errorMessage = "value is not a number"; | |
return false; | |
} | |
break; | |
} | |
} | |
context.errorMessage = ""; | |
return true; | |
}, | |
// cant figure out how to 'chain' guards (https://github.com/statelyai/xstate/issues/414) so just copying and pasting code for now | |
checkQuantityValuePickup: (context, event) => { | |
if (!context.isPickup) { | |
return false; | |
} | |
event = event ; | |
switch (event.input_type) { | |
case "text": | |
if (!event.value) { | |
console.log("EVENT VALUE", event.value); | |
context.errorMessage = "value is not a number"; | |
return false; | |
} | |
break; | |
case "number": { | |
const value = Number(event.value); | |
if (isNaN(value)) { | |
context.errorMessage = "value is not a number"; | |
return false; | |
} | |
break; | |
} | |
} | |
context.errorMessage = ""; | |
return true; | |
}, | |
checkQuantityValueDelivery: (context, event) => { | |
if (context.isPickup) { | |
return false; | |
} | |
event = event ; | |
switch (event.input_type) { | |
case "text": | |
if (!event.value) { | |
console.log("EVENT VALUE", event.value); | |
context.errorMessage = "value is not a number"; | |
return false; | |
} | |
break; | |
case "number": { | |
const value = Number(event.value); | |
if (isNaN(value)) { | |
context.errorMessage = "value is not a number"; | |
return false; | |
} | |
break; | |
} | |
} | |
context.errorMessage = ""; | |
return true; | |
}, | |
// /cant figure out chaining guards | |
}, | |
actions: { | |
updateTimestamp: context => { | |
context.timestamp = Date.now(); | |
}, | |
resetContext: context => { | |
context.comment = ""; | |
context.updatingQuantity = false; | |
context.verifiedQuantity = false; | |
}, | |
setCommentField: (context, event) => { | |
context.comment = event.comment ? event.comment : ""; | |
}, | |
verifiedQuantityTrue: context => (context.verifiedQuantity = true), | |
updatingQuantityTrue: context => (context.updatingQuantity = true), | |
updatingQuantityFalse: context => (context.updatingQuantity = false), | |
setQuantity: (context, event) => { | |
event = event ; | |
context.quantityActual = Number(event.value); | |
}, | |
setPlanned: context => (context.isPlanned = true), | |
setNotPlanned: context => (context.isPlanned = false), | |
}, | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment