import type { Store } from 'redux' ; import { shallowEqualByKeys } from 'refun' ; import type { TMetaState } from '../store-meta/types' ; import { updateComponentProps } from '../store-meta' ; import { objectPick } from '../utils/object-pick' ; import { navigate } from '../store' ; import type { TState as TMainState } from '../store/types' ; import type { TSyncStore , TMainSubState , TMetaSubState , TSyncState } from './types' ; import { mainStateKeys , metaStateKeys } from './get-initial-sync-state' ; import { isValidSyncState } from './is-valid-sync-state' ; export const SyncStoreFactory = ( mainStore , metaStore ) : TSyncStore => { let mainKnownState = objectPick ( mainStore . getState ( ) , mainStateKeys ) ; let metaKnownState = objectPick ( metaStore . getState ( ) , metaStateKeys ) ; let isMainStateUpdating = false ; let isMetaStateUpdating = false ; const subscribers = new Set ( ) ; const callSubscribers = ( state ) => { for ( const sub of subscribers ) { sub ( state ) ; } } ; mainStore . subscribe ( ( ) => { if ( isMainStateUpdating ) { return ; } const state = objectPick ( mainStore . getState ( ) , mainStateKeys ) ; if ( shallowEqualByKeys ( mainKnownState , state , mainStateKeys ) ) { return ; } mainKnownState = state ; callSubscribers ( { ... state , ... metaKnownState , } ) ; } ) ; metaStore . subscribe ( ( ) => { if ( isMetaStateUpdating ) { return ; } const state = objectPick ( metaStore . getState ( ) , metaStateKeys ) ; if ( shallowEqualByKeys ( metaKnownState , state , metaStateKeys ) ) { return ; } metaKnownState = state ; callSubscribers ( { ... mainKnownState , ... state , } ) ; } ) ; return { setState : async ( incoming ) => { if ( ! isValidSyncState ( incoming ) ) { return ; } const incomingMainState = objectPick ( incoming , mainStateKeys ) ; if ( ! shallowEqualByKeys ( incomingMainState , mainKnownState , mainStateKeys ) ) { mainKnownState = incomingMainState ; isMainStateUpdating = true ; navigate ( incomingMainState ) ; isMainStateUpdating = false ; } const incomingMetaState = objectPick ( incoming , metaStateKeys ) ; if ( ! shallowEqualByKeys ( incomingMetaState , metaKnownState , metaStateKeys ) ) { metaKnownState = incomingMetaState ; isMetaStateUpdating = true ; await updateComponentProps ( incomingMetaState . componentKey , incomingMetaState . propsIndex ) ; isMetaStateUpdating = false ; } } , subscribe : ( observer ) => { subscribers . add ( observer ) ; } , } ; } ;