Skip to content

Instantly share code, notes, and snippets.

@felippenardi
Created February 14, 2020 18:55
Show Gist options
  • Save felippenardi/ee85db13a2b9f12ee1e99ba3cb3465f0 to your computer and use it in GitHub Desktop.
Save felippenardi/ee85db13a2b9f12ee1e99ba3cb3465f0 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
var contentEditorMachine = Machine({
id: 'content',
strict: true,
initial: 'unknown',
context: {
variants: [
{ id: '1', status: 'draft' },
{ id: '2', status: 'live' },
],
currentVariant: {
id: '1',
status: 'draft'
}
},
states: {
unknown: {
id: 'unknown',
entry: 'calculateCurrentVariant',
on: {
'': [
{ target: 'live', cond: 'isLive' },
{ target: 'draft.viewing', cond: 'isDraft' },
{ target: 'draft.create' },
]
}
},
live: {
id: 'live',
initial: 'viewing',
states: {
viewing: {
on: {
EDIT: '#draft.create',
CHANGE_VARIANT: {
target: '#unknown',
actions: 'changeCurrentVariant'
}
}
}
}
},
draft: {
id: 'draft',
initial: 'viewing',
states: {
create: {
type: 'parallel',
states: {
attempt: {
initial: 'enteringValues',
entry: 'clearCurrentVariant',
states: {
enteringValues: {
on: {
DISCARD: {
target: 'confirmingDiscard',
cond: 'hasOtherVariants',
actions: 'setNextVariant'
},
TRY: 'trying'
}
},
trying: {
invoke: {
src: function (ctx) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
var _a;
if (((_a = ctx) === null || _a === void 0 ? void 0 : _a.variants) && ctx.variants.length > 1) {
reject({ code: 'conflict' });
alreadyGotAnError = true;
}
else {
if (alreadyGotAnError) {
resolve();
alreadyGotAnError = false;
}
else {
reject();
alreadyGotAnError = true;
}
}
}, 2000);
});
},
onDone: {
target: '#unknown',
actions: 'updateVariants'
},
onError: [
{
target: 'conflictSolving',
cond: 'isConflictError'
},
{
target: 'enteringValues',
actions: send('ERROR')
},
]
}
},
confirmingDiscard: {
on: {
CONFIRM_DISCARD: '#unknown',
CANCEL_DISCARD: 'enteringValues'
}
},
conflictSolving: {
type: 'parallel',
states: {
solving: {
initial: 'confirming_override',
states: {
confirming_override: {
on: {
TRY: 'trying',
CANCEL: '#draft.create.attempt.enteringValues'
}
},
trying: {
invoke: {
src: function () {
return new Promise(function (resolve) {
setTimeout(function () { return resolve(); }, 2000);
});
},
onDone: '#unknown',
onError: {
target: 'confirming_override',
actions: send('ERROR')
}
}
}
}
},
error: {
initial: 'none',
states: {
none: {
on: {
ERROR: 'unknown'
}
},
unknown: {
on: {
DISMISS: 'none',
TRY: 'none'
}
}
}
}
}
}
}
},
error: {
initial: 'none',
states: {
none: {
on: {
ERROR: 'unknown'
}
},
unknown: {
on: {
DISMISS: 'none',
TRY: 'none'
}
}
}
}
}
},
edit: {
initial: 'makingChanges',
states: {
makingChanges: {
on: {
TRY_SAVING_CHANGES: 'saving',
DISCARD: {
target: 'confirmingDiscard',
cond: 'isAnotherVariant',
actions: 'setNextVariant'
}
}
},
confirmingDiscard: {
on: {
CONFIRM_DISCARD: '#unknown',
CANCEL_DISCARD: 'makingChanges'
}
},
saving: {
invoke: {
src: function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
if (alreadyGotAnError) {
resolve();
alreadyGotAnError = false;
}
else {
reject({ code: 'internal_server_error' });
alreadyGotAnError = true;
}
}, 2000);
});
},
onDone: '#unknown',
onError: {
target: 'makingChanges'
}
}
}
}
},
viewing: {
on: {
EDIT: 'edit',
CHANGE_VARIANT: {
target: '#unknown',
actions: 'changeCurrentVariant'
},
PUBLISH: 'publish'
}
},
publish: {
type: 'parallel',
states: {
attempt: {
initial: 'confirming_publish',
states: {
confirming_publish: {
on: {
TRY: 'trying',
CANCEL: '#draft.viewing'
}
},
trying: {
invoke: {
src: function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
var variants = [{ id: '2', status: 'live' }];
if (alreadyGotAnError) {
resolve(variants);
alreadyGotAnError = false;
}
else {
reject({ code: 'internal_server_error' });
alreadyGotAnError = true;
}
}, 2000);
});
},
onDone: {
target: '#unknown',
actions: 'updateVariants'
},
onError: {
target: 'confirming_publish',
actions: send('ERROR')
}
}
}
}
},
error: {
initial: 'none',
states: {
none: {
on: {
ERROR: 'unknown'
}
},
unknown: {
on: {
DISMISS: 'none',
TRY: 'none'
}
}
}
}
}
}
}
}
}
}, {
guards: {
isLive: function (ctx) { var _a, _b; return ((_b = (_a = ctx) === null || _a === void 0 ? void 0 : _a.currentVariant) === null || _b === void 0 ? void 0 : _b.status) === 'live'; },
isDraft: function (ctx) { var _a, _b; return ((_b = (_a = ctx) === null || _a === void 0 ? void 0 : _a.currentVariant) === null || _b === void 0 ? void 0 : _b.status) === 'draft'; },
hasOtherVariants: function (ctx) { var _a; return ((_a = ctx) === null || _a === void 0 ? void 0 : _a.variants) ? ctx.variants.length > 0 : false; },
isAnotherVariant: function (ctx, event) { var _a, _b, _c, _d; return ((_b = (_a = ctx) === null || _a === void 0 ? void 0 : _a.currentVariant) === null || _b === void 0 ? void 0 : _b.id) !== ((_d = (_c = event) === null || _c === void 0 ? void 0 : _c.variant) === null || _d === void 0 ? void 0 : _d.id); },
isConflictError: function (_, event) { var _a, _b; return ((_b = (_a = event) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.code) === 'conflict'; }
},
actions: {
// TODO: use assign({ errorCode: null}) format
clearCurrentVariant: assign(function (_) {
return {
currentVariant: null
};
}),
calculateCurrentVariant: assign(function (ctx) {
var _a, _b, _c, _d;
var nextVariant = ((_a = ctx) === null || _a === void 0 ? void 0 : _a.nextVariant) || ((_b = ctx) === null || _b === void 0 ? void 0 : _b.currentVariant) ||
(((_c = ctx) === null || _c === void 0 ? void 0 : _c.variants) && ((_d = ctx) === null || _d === void 0 ? void 0 : _d.variants[0])) ||
null;
return {
currentVariant: nextVariant,
nextVariant: null,
errorCode: null
};
}),
changeCurrentVariant: assign(function (_, event) {
var _a;
if (!((_a = event) === null || _a === void 0 ? void 0 : _a.variant)) {
return {};
}
return {
currentVariant: event.variant
};
}),
updateVariants: assign(function (_, event) {
var _a, _b;
var currentVariant = ((_a = event) === null || _a === void 0 ? void 0 : _a.data) && event.data[0];
return __assign(__assign({}, (currentVariant ? { currentVariant: currentVariant } : {})), (((_b = event) === null || _b === void 0 ? void 0 : _b.data) ? { variants: event.data } : {}));
}),
setNextVariant: assign(function (_, event) {
var _a;
if (!((_a = event) === null || _a === void 0 ? void 0 : _a.variant)) {
return {};
}
return {
nextVariant: event.variant
};
})
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment