import { combineEpics , ofType } from 'redux-observable' ; import { of , from , zip } from 'rxjs' ; import { map , mergeMap , filter , tap , withLatestFrom , ignoreElements , pairwise , } from 'rxjs/operators' ; import * as Cfg from '../config' ; import { getAnalyticsConfig } from './selectors' ; import { initializeMixpanel , setMixpanelTracking , trackEvent } from './mixpanel' ; import { makeEvent } from './make-event' ; import type { Observable } from 'rxjs' ; import type { State , Action , Epic } from '../types' ; import type { ConfigInitializedAction } from '../config/types' ; import type { TrackEventArgs , AnalyticsEvent , AnalyticsConfig } from './types' ; const initializeAnalyticsEpic = ( action$ , state$ ) => { return action$ . pipe ( ofType < Action , ConfigInitializedAction > ( Cfg . INITIALIZED ) , tap ( ( initAction ) => { const { config } = initAction . payload ; initializeMixpanel ( config . analytics ) ; } ) , ignoreElements ( ) ) ; } ; const sendAnalyticsEventEpic = ( action$ , state$ ) => { return action$ . pipe ( withLatestFrom ( state$ ) , mergeMap < [ Action , State ] , Observable < TrackEventArgs > > ( ( [ action , state ] ) => { const event$ = from ( makeEvent ( action , state ) ) ; return zip ( event$ , of ( getAnalyticsConfig ( state ) ) ) ; } ) , filter < TrackEventArgs , [ AnalyticsEvent , AnalyticsConfig ] > ( ( args ) : args is [ AnalyticsEvent , AnalyticsConfig ] => { const [ maybeEvent , maybeConfig ] = args ; return Boolean ( maybeEvent && maybeConfig ) ; } ) , tap ( ( [ event , config ] ) => trackEvent ( event , config ) ) , ignoreElements ( ) ) ; } ; const optIntoAnalyticsEpic = ( _ , state$ ) => { return state$ . pipe ( map < State , AnalyticsConfig | null > ( getAnalyticsConfig ) , filter < AnalyticsConfig | null , AnalyticsConfig > ( ( maybeConfig ) : maybeConfig is AnalyticsConfig => maybeConfig !== null ) , pairwise ( ) , filter ( ( [ prev , next ] ) => prev . optedIn !== next . optedIn ) , tap ( ( [ _ , config ] ) => setMixpanelTracking ( config ) ) , ignoreElements ( ) ) ; } ; export const analyticsEpic = combineEpics < Epic > ( initializeAnalyticsEpic , sendAnalyticsEventEpic , optIntoAnalyticsEpic ) ;