Refactor app state to be a state machine with access selectors
This commit is contained in:
134
web/components/stores/application-state.ts
Normal file
134
web/components/stores/application-state.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
This is a finite state machine model that is used by xstate. https://xstate.js.org/
|
||||
You send events to it and it changes state based on the pre-determined
|
||||
modeling.
|
||||
This allows for a clean and reliable way to model the current state of the
|
||||
web application, and a single place to determine the flow of states.
|
||||
|
||||
You can paste this code into https://stately.ai/viz to see a visual state
|
||||
map or install the VS Code plugin:
|
||||
https://marketplace.visualstudio.com/items?itemName=statelyai.stately-vscode
|
||||
*/
|
||||
|
||||
import { createMachine } from 'xstate';
|
||||
|
||||
export interface AppStateOptions {
|
||||
chatAvailable: boolean;
|
||||
chatLoading?: boolean;
|
||||
videoAvailable: boolean;
|
||||
appLoading?: boolean;
|
||||
}
|
||||
|
||||
export function makeEmptyAppState(): AppStateOptions {
|
||||
return {
|
||||
chatAvailable: false,
|
||||
chatLoading: true,
|
||||
videoAvailable: false,
|
||||
appLoading: true,
|
||||
};
|
||||
}
|
||||
|
||||
const OFFLINE_STATE: AppStateOptions = {
|
||||
chatAvailable: false,
|
||||
chatLoading: false,
|
||||
videoAvailable: false,
|
||||
appLoading: false,
|
||||
};
|
||||
|
||||
const ONLINE_STATE: AppStateOptions = {
|
||||
chatAvailable: true,
|
||||
chatLoading: false,
|
||||
videoAvailable: true,
|
||||
appLoading: false,
|
||||
};
|
||||
|
||||
const LOADING_STATE: AppStateOptions = {
|
||||
chatAvailable: false,
|
||||
chatLoading: false,
|
||||
videoAvailable: false,
|
||||
appLoading: true,
|
||||
};
|
||||
|
||||
const GOODBYE_STATE: AppStateOptions = {
|
||||
chatAvailable: true,
|
||||
chatLoading: false,
|
||||
videoAvailable: false,
|
||||
appLoading: false,
|
||||
};
|
||||
|
||||
export enum AppStateEvent {
|
||||
Loading = 'LOADING',
|
||||
Loaded = 'LOADED',
|
||||
Online = 'ONLINE',
|
||||
Offline = 'OFFLINE', // Have not pulled configuration data from the server.
|
||||
NeedsRegister = 'NEEDS_REGISTER',
|
||||
Fail = 'FAIL',
|
||||
}
|
||||
|
||||
const appStateModel =
|
||||
/** @xstate-layout N4IgpgJg5mDOIC5QEMAOqDKAXZWwDoAbAe2QgEsA7KAYgCUBRAcQEkMAVBxgEUVFWKxyWcsUp8QAD0QBGAGwz8ABgCscpUoDsAZgAcKgEwrtATgA0IAJ6zNS-CZMLtcuQBY9Jg5t0BfHxbRMHDwiUgpqGgA5BgZuDAB9RlYOLgkBIRExCWkEGRVFVXUtPUNjcytEAxNXfB0DbSNNORMG119-EEDsXAISMipaABkAeQBBbli0wWFRcSQpWQVlNQ0dfSNTC2tc+vwZVwMZWxNbA5kDAz8A9G6QvvDaADFRlkGpjNns2VcCleL1spbRDaA74FS6ORVfYHTSObRXTo3YIEABOYCg5FgeBRA3ozDYnB47xmWXmOQOKj22hUnl02iajjk2iBCCqdgO2n2VRcbQhCK6yPwaIxWLAOIiz1exMyc1A5KMVJpBjpDJczIqCG0enwXk0MiUENMjiUBjk-KRPSFYDIlnwYkIVDANGGj0egxY0WlnzJiF0TXwulU9LqWhMMl0LIM7ipmguIIObU85qClrRNrtADMMw7KE7hpF3Z75ukSbKFgg5Pp7PSQdTXBp9uVtlHtDG464E7okx0BanrRBbVBiMQIAAjSxOyRYy3IDPYgAU2g0y4AlDReyE0wP8EOR+OwF7SXLff7A8ZNCHYeGWedW3qlDIWkz61rLgjKCO4BIN70wgND2W8o3pyyjKrCdZ6q4sYqMmtyouimLYv+xbTDKXyakuyiuHI+QmCoJquCo2FyCyS52PURzqI+mgqIYpqwYKW62vajoAehsJyFS+paPhfoRhqUa6PgTIuLoRznComiEWaPYWpu-bMVmOYHihHxHuWRQ6pCJz0sqGgNMBBjCfohiEUoIJ0kyDF9umu5jhObE+rkqh2BCLS8XhYa6K4wGUuGtEviYZ5qNZ8k2o5x4IJJnGmlUOixoG5kGCy+G1JyXgHGJJhKByrihQQsBigAbmKjzIOQhAAK5ohF5YXJx+q2MYbieFB4KkW0yj6NBfr6vU3n5fglWFSiGblVVNWqaW6H5HY4bNFJbhKI4HV3k0rgnNlS6xm+1wpngtU5NeGoALQXDqbVBct+g5Qofh+EAA */
|
||||
createMachine({
|
||||
id: 'appState',
|
||||
initial: 'loading',
|
||||
states: {
|
||||
loading: {
|
||||
meta: {
|
||||
...LOADING_STATE,
|
||||
},
|
||||
on: {
|
||||
NEEDS_REGISTER: {
|
||||
target: 'loading',
|
||||
},
|
||||
LOADED: {
|
||||
target: 'ready',
|
||||
},
|
||||
FAIL: {
|
||||
target: 'serverFailure',
|
||||
},
|
||||
},
|
||||
},
|
||||
ready: {
|
||||
initial: 'offline',
|
||||
states: {
|
||||
online: {
|
||||
meta: {
|
||||
...ONLINE_STATE,
|
||||
},
|
||||
on: {
|
||||
OFFLINE: {
|
||||
target: 'goodbye',
|
||||
},
|
||||
},
|
||||
},
|
||||
offline: {
|
||||
meta: {
|
||||
...OFFLINE_STATE,
|
||||
},
|
||||
on: {
|
||||
ONLINE: {
|
||||
target: 'online',
|
||||
},
|
||||
},
|
||||
},
|
||||
goodbye: {
|
||||
meta: {
|
||||
...GOODBYE_STATE,
|
||||
},
|
||||
after: {
|
||||
'300000': {
|
||||
target: 'offline',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
serverFailure: {
|
||||
type: 'final',
|
||||
},
|
||||
userfailure: {
|
||||
type: 'final',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default appStateModel;
|
||||
Reference in New Issue
Block a user