import type { MonitoringAdapter , Monitoring } from '@resolve-js/core' ; const wrapVoidMethod = < K extends keyof Omit < Monitoring , 'group' | 'publish' | 'performance' > , P extends Parameters < Monitoring [ K ] > > ( methodName , adapterMap ) : ( ( ... args : P ) => void ) => { return ( ... args ) => { Object . keys ( adapterMap ) . forEach ( ( id ) => { void ( adapterMap [ id ] [ methodName ] as any ) . apply ( adapterMap [ id ] , args ) ; } ) ; } ; } ; const createCompositeAdapterImplementation = ( adapterMap ) : Monitoring => { return { group : ( config ) => { const nextAdapterMap = Object . keys ( adapterMap ) . reduce ( ( acc , id ) => ( { ... acc , [ id ] : adapterMap [ id ] . group ( config ) , } ) , { } as Record < string , MonitoringAdapter > ) ; return createCompositeAdapterImplementation ( nextAdapterMap ) ; } , execution : wrapVoidMethod ( 'execution' , adapterMap ) , rate : wrapVoidMethod ( 'rate' , adapterMap ) , error : wrapVoidMethod ( 'error' , adapterMap ) , duration : wrapVoidMethod ( 'duration' , adapterMap ) , custom : wrapVoidMethod ( 'custom' , adapterMap ) , time : wrapVoidMethod ( 'time' , adapterMap ) , timeEnd : wrapVoidMethod ( 'timeEnd' , adapterMap ) , publish : async ( ... args ) => { await Promise . all ( Object . keys ( adapterMap ) . map ( async ( id ) => adapterMap [ id ] . publish ( ... args ) ) ) ; } , getMetrics : ( id ) => { const adapter = adapterMap [ id ] ; if ( adapter == null ) { throw new Error ( `Monitoring adapter with '${ id }' id not found` ) ; } return adapter . getMetrics ( ) ; } , clearMetrics : ( id ) => { const adapter = adapterMap [ id ] ; if ( adapter == null ) { throw new Error ( `Monitoring adapter with '${ id }' id not found` ) ; } return adapter . clearMetrics ( ) ; } , } ; } ; export const createCompositeMonitoringAdapter = ( adapterCreators ) : Monitoring => { const ids = Object . keys ( adapterCreators ) ; const adapterMap = ids . reduce ( ( acc , id ) => ( { ... acc , [ id ] : adapterCreators [ id ] ( ) } ) , { } as Record < string , MonitoringAdapter > ) ; return createCompositeAdapterImplementation ( adapterMap ) ; } ;