mirror of
				https://github.com/owncast/owncast.git
				synced 2025-10-31 10:08:10 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			149 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /*
 | |
| 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', // Have not pulled configuration data from the server.
 | |
|   Loaded = 'LOADED', // Configuration data has been pulled from the server.
 | |
|   Online = 'ONLINE', // Stream is live
 | |
|   Offline = 'OFFLINE', // Stream is not live
 | |
|   NeedsRegister = 'NEEDS_REGISTER', // Needs to register a chat user
 | |
|   Fail = 'FAIL', // Error
 | |
|   ChatUserDisabled = 'CHAT_USER_DISABLED', // Chat user is disabled
 | |
| }
 | |
| 
 | |
| 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',
 | |
|     predictableActionArguments: true,
 | |
|     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',
 | |
|               },
 | |
|               CHAT_USER_DISABLED: {
 | |
|                 target: 'chatUserDisabled',
 | |
|               },
 | |
|             },
 | |
|           },
 | |
|           offline: {
 | |
|             meta: {
 | |
|               ...OFFLINE_STATE,
 | |
|             },
 | |
|             on: {
 | |
|               ONLINE: {
 | |
|                 target: 'online',
 | |
|               },
 | |
|             },
 | |
|           },
 | |
|           goodbye: {
 | |
|             on: {
 | |
|               ONLINE: {
 | |
|                 target: 'online',
 | |
|               },
 | |
|             },
 | |
|             meta: {
 | |
|               ...GOODBYE_STATE,
 | |
|             },
 | |
|             after: {
 | |
|               '300000': {
 | |
|                 target: 'offline',
 | |
|               },
 | |
|             },
 | |
|           },
 | |
|           chatUserDisabled: {
 | |
|             meta: {
 | |
|               ...ONLINE_STATE,
 | |
|               chatAvailable: false,
 | |
|             },
 | |
|           },
 | |
|         },
 | |
|       },
 | |
|       serverFailure: {
 | |
|         type: 'final',
 | |
|       },
 | |
|       userfailure: {
 | |
|         type: 'final',
 | |
|       },
 | |
|     },
 | |
|   });
 | |
| 
 | |
| export default appStateModel;
 | 
