@@ -218,6 +218,11 @@ function isString(x: unknown): x is string {
218218 return typeof x === 'string' || x instanceof String ;
219219}
220220
221+ export type TargetFactory <
222+ SCG extends ExtendableGenerics = DefaultGenerics ,
223+ T extends Exclude < EventTypes , 'all' > = Exclude < EventTypes , 'all' >
224+ > = ( event : Event < SCG > ) => `${T } ${string } ` | `${string } ${T } ` | `${string } ${T } ${string } ` | null ;
225+
221226export class StreamChat < StreamChatGenerics extends ExtendableGenerics = DefaultGenerics > {
222227 private static _instance ?: unknown | StreamChat ; // type is undefined|StreamChat, unknown is due to TS limitations with statics
223228
@@ -269,6 +274,7 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
269274 defaultWSTimeoutWithFallback : number ;
270275 defaultWSTimeout : number ;
271276 private nextRequestAbortController : AbortController | null = null ;
277+ private targetFactoriesByType = new Map < Exclude < EventTypes , 'all' > , Set < TargetFactory < StreamChatGenerics > > > ( ) ;
272278
273279 /**
274280 * Initialize a client
@@ -909,6 +915,28 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
909915 return JWTUserToken ( this . secret , userID , extra , { } ) ;
910916 }
911917
918+ public registerTargetFactory = < T extends Exclude < EventTypes , 'all' > > (
919+ eventType : T ,
920+ factory : TargetFactory < StreamChatGenerics , T > ,
921+ ) => {
922+ let set = this . targetFactoriesByType . get ( eventType ) ;
923+
924+ if ( ! set ) {
925+ set = new Set ( ) ;
926+ this . targetFactoriesByType . set ( eventType , set ) ;
927+ }
928+
929+ set . add ( factory ) ;
930+
931+ return ( ) => {
932+ set . delete ( factory ) ;
933+
934+ if ( ! set . size ) {
935+ this . targetFactoriesByType . delete ( eventType ) ;
936+ }
937+ } ;
938+ } ;
939+
912940 /**
913941 * on - Listen to events on all channels and users your watching
914942 *
@@ -936,6 +964,7 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
936964 tags : [ 'event' , 'client' ] ,
937965 } ) ;
938966 this . listeners [ key ] . push ( callback ) ;
967+
939968 return {
940969 unsubscribe : ( ) => {
941970 this . logger ( 'info' , `Removing listener for ${ key } event` , {
@@ -1364,8 +1393,21 @@ export class StreamChat<StreamChatGenerics extends ExtendableGenerics = DefaultG
13641393 if ( client . listeners . all ) {
13651394 listeners . push ( ...client . listeners . all ) ;
13661395 }
1367- if ( client . listeners [ event . type ] ) {
1368- listeners . push ( ...client . listeners [ event . type ] ) ;
1396+
1397+ const eventTypes : string [ ] = [ event . type ] ;
1398+
1399+ // factories
1400+ const factorySet = client . targetFactoriesByType . get ( event . type as Exclude < EventTypes , 'all' > ) ;
1401+ factorySet ?. forEach ( ( factory ) => {
1402+ // a specific value could be missing from the event payload so factory can return "null" to be skipped
1403+ const targetedEventType = factory ( event ) ;
1404+ if ( targetedEventType ) eventTypes . push ( targetedEventType ) ;
1405+ } ) ;
1406+
1407+ for ( const eventType of eventTypes ) {
1408+ if ( client . listeners [ eventType ] ) {
1409+ listeners . push ( ...client . listeners [ eventType ] ) ;
1410+ }
13691411 }
13701412
13711413 // call the event and send it to the listeners
0 commit comments