Created
March 2, 2020 23:19
-
-
Save mergebandit/934387e319551a67fc979c0efff03624 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
This file contains hidden or 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
| const service = { | |
| addMfa: mfaOpt => { | |
| console.log("service call: addMfa", mfaOpt); | |
| return Promise.resolve(mfaOpt); | |
| }, | |
| deleteMfa: mfaOpt => { | |
| console.log("service call: deleteMfa", mfaOpt); | |
| return Promise.resolve(mfaOpt.mfaId); | |
| }, | |
| verifyMfa: mfaOpt => { | |
| console.log("service call: verifyMfa", mfaOpt); | |
| return Promise.resolve(mfaOpt.mfaId); | |
| }, | |
| sendCode: selectedMfaOption => { | |
| console.log("service call: sendCode", selectedMfaOption); | |
| return Promise.resolve(selectedMfaOption); | |
| }, | |
| verifyCode: (code, mfaOpt) => { | |
| console.log("service call: verifyCode", code, mfaOpt.mfaType); | |
| return Promise.resolve({ | |
| ...mfaOpt, | |
| mfaIdentifier: "vcxjklvxjkjfsjkljfasjklfsdjkl" | |
| }); | |
| } | |
| }; | |
| const createCodeMachine = context => | |
| Machine( | |
| { | |
| context: { | |
| code: "1234", | |
| errorMessage: "", | |
| selectedMfaOption: undefined, | |
| ...context | |
| }, | |
| id: "code", | |
| initial: "sending", | |
| meta: { | |
| nextLabel: "Confirm", | |
| pageTitle: "Enter Confirmation Code", | |
| prevLabel: "Back" | |
| }, | |
| on: { | |
| PREV: { | |
| actions: sendParent("PREV") | |
| }, | |
| RESEND: "sending", | |
| UPDATE: { | |
| actions: "setCode" | |
| } | |
| }, | |
| states: { | |
| sending: { | |
| invoke: { | |
| id: "sendingCode", | |
| src: "sendCode", | |
| onError: { | |
| actions: "setError", | |
| target: "failure" | |
| }, | |
| onDone: { | |
| target: "idle" | |
| } | |
| } | |
| }, | |
| complete: { | |
| data: { | |
| code: ({ code }) => code | |
| }, | |
| type: "final" | |
| }, | |
| idle: { | |
| on: { | |
| NEXT: "saving" | |
| } | |
| }, | |
| failure: { | |
| on: { | |
| NEXT: "saving" | |
| } | |
| }, | |
| saving: { | |
| invoke: { | |
| id: "saving", | |
| src: "verifyCode", | |
| onError: { | |
| actions: "setError", | |
| target: "failure" | |
| }, | |
| onDone: { | |
| target: "complete", | |
| actions: "foo" | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| { | |
| actions: { | |
| foo: sendParent((_, evt) => ({ | |
| type: "COMPLETE", | |
| data: evt.data | |
| })), | |
| setCode: assign({ | |
| code: (_, event) => event.value | |
| }), | |
| setError: assign({ | |
| errorMessage: (_, event) => event.data | |
| }) | |
| }, | |
| services: { | |
| sendCode: ({ selectedMfaOption }) => | |
| service.sendCode(selectedMfaOption), | |
| verifyCode: ({ code, selectedMfaOption }) => | |
| service.verifyCode(code, selectedMfaOption) | |
| } | |
| } | |
| ); | |
| const notificationMachine = Machine( | |
| { | |
| id: "notification", | |
| initial: "idle", | |
| context: { | |
| message: "" | |
| }, | |
| states: { | |
| idle: { | |
| on: { | |
| NOTIFY: { | |
| target: "visible", | |
| actions: assign({ | |
| message: (_, e) => e.data | |
| }) | |
| } | |
| } | |
| }, | |
| visible: { | |
| entry: "addNotification", | |
| on: { | |
| "": "idle" | |
| } | |
| } | |
| } | |
| }, | |
| { | |
| actions: { | |
| addNotification: ctx => { | |
| console.error("Notification:", ctx.message); | |
| } | |
| } | |
| } | |
| ); | |
| const notificationFactory = payload => ({ | |
| type: "setNotificationMessage", | |
| payload | |
| }); | |
| const manageMachine = Machine( | |
| { | |
| id: "manage", | |
| initial: "list", | |
| entry: assign({ | |
| notificationMachine: () => spawn(notificationMachine) | |
| }), | |
| context: { | |
| mfaOptions: [ | |
| { | |
| mfaIdentier: "afkalasjlkdjklsfsd", | |
| mfaId: "1234567890", | |
| mfaType: "sms" | |
| }, | |
| { | |
| mfaIdentier: "bnwrkenrkkrewnkrejw", | |
| mfaId: "0987654321", | |
| mfaType: "sms" | |
| }, | |
| { | |
| mfaIdentier: "buiyryuiryuertuiyuit", | |
| mfaId: "[email protected]", | |
| mfaType: "email" | |
| } | |
| ], | |
| // selectedMfaOption: { mfaId: "1234567890" }, | |
| selectedMfaOption: null, | |
| phoneMethod: null, | |
| email: null, | |
| phone: null, | |
| notificationMessage: null, | |
| frequency: null, | |
| deleteMachine: null, | |
| addMachine: null, | |
| frequencyMachine: null, | |
| codeMachine: null, | |
| notificationMachine: null | |
| }, | |
| states: { | |
| profile: { | |
| after: { | |
| 750: "list" | |
| } | |
| }, | |
| list: { | |
| id: "list", | |
| on: { | |
| DELETE_MFA: { | |
| target: "delete", | |
| actions: "selectMfa" | |
| }, | |
| ADD_EMAIL: "add.email", | |
| ADD_PHONE: "add.phone", | |
| PREV: "#manage.profile" | |
| } | |
| }, | |
| add: { | |
| states: { | |
| email: { | |
| initial: "idle", | |
| on: { | |
| PREV: "#list", | |
| NEXT: ".adding" | |
| }, | |
| states: { | |
| error: {}, | |
| idle: { | |
| on: { | |
| UPDATE: { | |
| actions: "setEmail" | |
| } | |
| } | |
| }, | |
| adding: { | |
| entry: "selectMfa", | |
| invoke: { | |
| id: "addMfa", | |
| src: "addMfa", | |
| onDone: { | |
| target: "#enterCode", | |
| actions: [ | |
| notificationFactory("Email address added"), | |
| "clearEmail" | |
| ] | |
| }, | |
| onError: "error" | |
| } | |
| } | |
| } | |
| }, | |
| phone: { | |
| initial: "idle", | |
| on: { | |
| PREV: "#list", | |
| UPDATE: { | |
| target: ".idle", | |
| actions: "setPhone" | |
| } | |
| }, | |
| states: { | |
| error: {}, | |
| idle: { | |
| on: { | |
| NEXT: "method" | |
| } | |
| }, | |
| method: { | |
| on: { | |
| CHANGE: { | |
| actions: "setPhoneMethod" | |
| }, | |
| NEXT: "adding" | |
| } | |
| }, | |
| adding: { | |
| entry: "selectMfa", | |
| invoke: { | |
| id: "addMfa", | |
| src: "addMfa", | |
| onDone: { | |
| target: "#enterCode", | |
| actions: [ | |
| notificationFactory("Phone Number added"), | |
| 'clearPhone' | |
| ] | |
| }, | |
| onError: "error" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| // code: { | |
| // id: "code", | |
| // on: { | |
| // NEXT: ".verifying" | |
| // }, | |
| // states: { | |
| // addEmail: { | |
| // on: { | |
| // PREV: "#manage.add.email.idle" | |
| // } | |
| // }, | |
| // addPhone: { | |
| // on: { | |
| // PREV: "#manage.add.phone" | |
| // } | |
| // }, | |
| // error: {}, | |
| // verifying: { | |
| // invoke: { | |
| // id: "verifyMfa", | |
| // src: "verifyMfa", | |
| // onDone: { | |
| // target: "#list", | |
| // actions: [ | |
| // "sendNotification", | |
| // "clearMfaOption", | |
| // "clearEmail", | |
| // "clearPhone" | |
| // ] | |
| // }, | |
| // onError: "error" | |
| // } | |
| // } | |
| // } | |
| // }, | |
| delete: { | |
| initial: "idle", | |
| states: { | |
| error: {}, | |
| idle: { | |
| on: { | |
| PREV: "#list", | |
| NEXT: "deleting" | |
| } | |
| }, | |
| deleting: { | |
| invoke: { | |
| id: "deleteMfa", | |
| src: "deleteMfa", | |
| onDone: { | |
| target: "#list", | |
| actions: [ | |
| assign({ | |
| notificationMessage: (ctx, { data }) => | |
| `${ | |
| data.mfaType === "email" ? "Email" : "Phone Number" | |
| } Deleted` | |
| }), | |
| "sendNotification", | |
| "deleteMfaFromCtx" | |
| ] | |
| }, | |
| onError: "error" | |
| } | |
| } | |
| } | |
| }, | |
| enteringCode: { | |
| id: "enterCode", | |
| initial: "idle", | |
| entry: [ | |
| assign({ | |
| codeMachine: ({ selectedMfaOption }) => | |
| spawn(createCodeMachine({ selectedMfaOption })) | |
| }) | |
| ], | |
| states: { | |
| idle: { | |
| on: { | |
| NEXT: { | |
| actions: send("NEXT", { to: ctx => ctx.codeMachine }) | |
| }, | |
| COMPLETE: { | |
| target: "#list", | |
| actions: ["updateMfa", "sendNotification"] | |
| } | |
| } | |
| } | |
| }, | |
| on: { | |
| PREV: "#list" | |
| } | |
| }, | |
| complete: { | |
| type: "final" | |
| } | |
| } | |
| }, | |
| { | |
| actions: { | |
| updateMfa: assign({ | |
| selectedMfaOption: null, | |
| mfaOptions: (ctx, evt) => [...ctx.mfaOptions, evt.data] | |
| }), | |
| addMfaToCtx: assign({ | |
| mfaOptions: (ctx, evt) => [...ctx.mfaOptions, evt.data] | |
| }), | |
| deleteMfaFromCtx: assign({ | |
| mfaOptions: (ctx, evt) => | |
| ctx.mfaOptions.filter(opt => opt.mfaId !== evt.data), | |
| selectedMfaOption: null | |
| }), | |
| selectMfa: assign({ | |
| selectedMfaOption: ({ email, phone, mfaOptions }, { data }) => | |
| data | |
| ? mfaOptions.find(opt => opt.mfaId === data) | |
| : { | |
| mfaId: email || phone, | |
| mfaType: email ? "email" : "sms" | |
| } | |
| }), | |
| setNotificationMessage: assign({ | |
| notificationMessage: 'notif sent' | |
| }), | |
| sendNotification: send( | |
| ctx => ({ | |
| type: "NOTIFY", | |
| data: ctx.notificationMessage | |
| }), | |
| { | |
| to: ctx => ctx.notificationMachine | |
| } | |
| ), | |
| setEmail: assign({ | |
| email: (_, evt) => evt.data | |
| }), | |
| setPhone: assign({ | |
| phone: (_, evt) => evt.data | |
| }), | |
| setPhoneMethod: assign({ | |
| phoneMethod: (_, evt) => evt.data | |
| }), | |
| clearMfaOption: assign({ | |
| selectedMfaOption: null | |
| }), | |
| clearPhone: assign({ | |
| phone: null | |
| }), | |
| clearEmail: assign({ | |
| email: null | |
| }) | |
| }, | |
| services: { | |
| addMfa: ({ email, phone }) => | |
| service.addMfa({ | |
| mfaId: email || phone, | |
| mfaType: email ? "email" : "phone" | |
| }), | |
| deleteMfa: (ctx, evt) => service.deleteMfa(ctx.selectedMfaOption), | |
| verifyMfa: (ctx, evt) => service.verifyMfa(ctx.selectedMfaOption) | |
| }, | |
| guards: { | |
| isMfaOptionSelected: ctx => | |
| ctx.selectedMfaOption ? !!ctx.selectedMfaOption.mfaId : false | |
| } | |
| } | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment