import { useCallback, useMemo, useReducer, } from 'react'; import compareCallback from './compareCallback'; import ctaReducer, { type CTAReducerState, } from './ctaReducer'; import type { UseCTAParameterOnInit, } from '../types/UseCTAParameterOnInit'; import type { CTAState, } from '../types/CTAState'; import type { UseCTAParameter, } from '../types/UseCTAParameter'; function _init< Initial extends CTAState, >( privateCTAState: CTAReducerState, init?: UseCTAParameterOnInit, ): CTAReducerState { const changesMap = new Map() as CTAReducerState['changesMap']; if ( typeof init !== 'function' ) { return { ...privateCTAState, changesMap, }; } const initial = init( privateCTAState.current, ); return { ...privateCTAState, changesMap, current: initial, initial, }; } export default function usePrivateCTA< Initial extends CTAState, Actions, >( params: UseCTAParameter, actions?: UseCTAParameter['actions'], ) { const compare = useMemo( () => compareCallback( params.compare, ), // eslint-disable-next-line react-hooks/exhaustive-deps [ ], ); const init = useMemo>( () => ( { actionType: '' as CTAReducerState['actionType'], customAction: undefined, changes: null, // Set changesMap in init to avoid re-instantiating a new Map everytime this is called changesMap: undefined as unknown as CTAReducerState['changesMap'], current: params.initial, initial: params.initial, previous: null, previousInitial: null, } ), // eslint-disable-next-line react-hooks/exhaustive-deps [ ], ); const reducerCallback = useCallback( ( ctaReducerState: CTAReducerState, nextCTAProps: Parameters>[0]['nextCTAProps'], ) => ctaReducer( { actions, compare, ctaReducerState, nextCTAProps, transform: params.transform, }, ), // eslint-disable-next-line react-hooks/exhaustive-deps [], ); const onInit = useCallback( ( privateCTAState: CTAReducerState, ) => _init( privateCTAState, params.onInit, ), // eslint-disable-next-line react-hooks/exhaustive-deps [], ); return useReducer( reducerCallback, init, onInit, ); } export type UsePrivateCTAReturnType< Initial extends CTAState, Actions, > = ReturnType>;