import { AnyAction , EnhancedActions , Manager , ManagerFactory , SideEffect } from '@fluentui/state' ; import * as React from 'react' ; type UseStateManagerOptions < State > = { mapPropsToInitialState ? : ( ) => Partial < State > ; mapPropsToState ? : ( ) => Partial < State > ; sideEffects ? : SideEffect < State > [ ] ; } ; type UseStateManagerResult < State , Actions > = { state : Readonly < State > ; actions : Readonly < Actions > ; } ; const getDefinedProps = < Props extends Record < string , any > > ( props ) : Partial < Props > => { const definedProps = { } ; Object . keys ( props ) . forEach ( propName => { if ( props [ propName ] !== undefined ) { ; ( < Record < string , any > > definedProps ) [ propName ] = props [ propName ] ; } } ) ; return definedProps ; } ; const useStateManager = < State extends Record < string , any > , Actions extends Record < string , AnyAction > > ( managerFactory , options = { } ) : UseStateManagerResult < State , Actions > => { const { mapPropsToInitialState = ( ) => ( { } as Partial < State > ) , mapPropsToState = ( ) => ( { } as Partial < State > ) , sideEffects = [ ] , } = options ; const latestActions = React . useMemo < Actions > ( ( ) => ( { } as Actions ) , [ managerFactory ] ) ; const latestManager = React . useRef < Manager < State , Actions > | null > ( null ) ; const [ , forceUpdate ] = React . useReducer ( ( c ) => c + 1 , 0 ) as [ never , ( ) => void ] ; const initialState = latestManager . current ? latestManager . current . state : getDefinedProps ( mapPropsToInitialState ( ) ) ; latestManager . current = managerFactory ( { actions : { } as EnhancedActions < State , Actions > , state : { ... initialState , ... getDefinedProps ( mapPropsToState ( ) ) } , sideEffects : [ ... sideEffects , ( ) => forceUpdate ( ) , ] , } ) ; Object . assign ( latestActions , latestManager . current . actions ) ; if ( process . env . NODE_ENV !== 'production' ) { if ( Object . isExtensible ( latestActions ) ) Object . preventExtensions ( latestActions ) ; } return { state : process . env . NODE_ENV === 'production' ? latestManager . current . state : Object . freeze ( latestManager . current . state ) , actions : latestActions , } ; } ; export default useStateManager ;