import * as React from 'react' ; import { useStateMachineContext } from './StateMachineContext' ; import storeFactory from './logic/storeFactory' ; import { setUpDevTools } from './logic/devTool' ; import { StateMachineOptions , GlobalState , AnyCallback , AnyActions , ActionsOutput , PersistOptions , } from './types' ; import { STORE_ACTION_NAME } from './constants' ; let persistOption = 'onAction' ; export function createStore ( defaultState , options ) { if ( options ) { options . name && ( storeFactory . name = options . name ) ; options . storageType && ( storeFactory . storageType = options . storageType ) ; options . middleWares && ( storeFactory . middleWares = options . middleWares ) ; options . persist && ( persistOption = options . persist ) ; } if ( process . env . NODE_ENV !== 'production' ) { setUpDevTools ( storeFactory . storageType , storeFactory . name , storeFactory . state ) ; } storeFactory . updateStore ( defaultState ) ; } const actionTemplate = < TCallback extends AnyCallback > ( setState , callback ) => ( payload ) => { if ( process . env . NODE_ENV !== 'production' ) { window [ STORE_ACTION_NAME ] = callback . name ; } storeFactory . state = callback ( storeFactory . state , payload ) ; if ( storeFactory . middleWares ) { storeFactory . state = storeFactory . middleWares . reduce ( ( currentValue , currentFunction ) => currentFunction ( currentValue , callback . name , payload ) || currentValue , storeFactory . state ) ; } setState ( storeFactory . state ) ; persistOption === 'onAction' && storeFactory . saveStore ( ) ; } ; export function useStateMachine < TCallback extends AnyCallback , TActions extends AnyActions < TCallback > > ( actions ? ) { const { state , setState } = useStateMachineContext ( ) ; const actionsRef = React . useRef ( Object . entries ( actions || { } ) . reduce ( ( previous , [ key , callback ] ) => Object . assign ( { } , previous , { [ key ] : actionTemplate ( setState , callback ) , } ) , { } as ActionsOutput < TCallback , TActions > ) ) ; React . useEffect ( ( ) => { if ( persistOption === 'beforeUnload' ) { window . onbeforeunload = ( ) => storeFactory . saveStore ( ) ; } } , [ ] ) ; return { actions : actionsRef . current , state , } ; }