import { PluginType , SegmentEvent , UpdateType } from './types' ; import type { Plugin } from './plugin' ; import { getAllPlugins } from './util' ; type TimelinePlugins = { [ key in PluginType ] ? : Plugin [ ] ; } ; export class Timeline { plugins : TimelinePlugins = { } ; add ( plugin ) { const { type } = plugin ; if ( this . plugins [ type ] ) { this . plugins [ type ] ?. push ( plugin ) ; } else { this . plugins [ type ] = [ plugin ] ; } const settings = plugin . analytics ?. settings . get ( ) ; if ( settings ) { plugin . update ( { integrations : settings } , UpdateType . initial ) ; } } remove ( plugin ) { const plugins = this . plugins [ plugin . type ] ; if ( plugins ) { const index = plugins . findIndex ( ( f ) => f === plugin ) ; if ( index > - 1 ) { plugins . splice ( index , 1 ) ; } } } apply ( closure ) { getAllPlugins ( this ) . forEach ( ( plugin ) => closure ( plugin ) ) ; } process ( incomingEvent ) { const beforeResult = this . applyPlugins ( { type : PluginType . before , event : incomingEvent , } ) ; if ( beforeResult === undefined ) { return ; } const enrichmentResult = this . applyPlugins ( { type : PluginType . enrichment , event : beforeResult , } ) ; this . applyPlugins ( { type : PluginType . destination , event : enrichmentResult , } ) ; let afterResult = this . applyPlugins ( { type : PluginType . after , event : enrichmentResult , } ) ; return afterResult ; } applyPlugins ( { type , event } ) { let result = event ; const plugins = this . plugins [ type ] ; if ( plugins ) { plugins . forEach ( ( plugin ) => { if ( result ) { result = plugin . execute ( result ) ; } } ) ; } return result ; } }