Machine({ id: "gameLauncher", type: "parallel", context: { error: null, launchedGame: null, launchRequest: null, }, states: { launcher: { initial: "browsing", states: { browsing: { on: { LAUNCH_GAME: [ { target: "launching", in: "#gameLauncher.session.loggedIn", actions: "assignLaunchRequest", }, { actions: ["assignLaunchRequest", "displayLogin"], }, ], }, }, launching: { invoke: { src: "requestLaunchGame", onDone: { target: "running", actions: assign({ launchedGame: (_, result) => result.data, }), }, onError: { target: "launchFailed", actions: assign({ error: (_, result) => result.data.error, }), }, }, initial: "loadingInBackground", states: { loadingInBackground: { onEntry: [send("SHOW_LOADING_SCREEN", { delay: 2000 })], on: { SHOW_LOADING_SCREEN: { target: "loadingScreen" }, }, }, loadingScreen: { on: { STOP_GAME: { target: "#gameLauncher.launcher.browsing", actions: ["unsetLaunchedGame"], }, }, }, }, }, running: { entry: "displayLaunchedGame", on: { STOP_GAME: { target: "browsing", actions: ["unsetLaunchedGame"], }, }, }, launchFailed: { on: { LAUNCH_GAME: [ { target: "launching.loadingInBackground", in: "#gameLauncher.session.loggedIn", actions: ["assignLaunchRequest", "removeError"], }, { target: "browsing", actions: [ "assignLaunchRequest", "removeError", "displayLogin", ], }, ], }, }, }, }, session: { initial: "notDetermined", states: { notDetermined: { on: { LOG_IN: { target: "loggedIn", }, LOG_OUT: { target: "loggedOut", }, }, }, loggedIn: { on: { LOG_OUT: { target: "loggedOut", }, }, }, loggedOut: { on: { LOG_IN: { target: "loggedIn", }, }, }, }, }, }, }, { actions: { assignLaunchRequest: assign({ launchRequest: (_, event) => event.launchRequest, }), removeError: assign({ error: () => null, }), unsetLaunchedGame: assign({ launchedGame: () => null, }), }, });