@@ -9,54 +9,78 @@ export class RoomKeyGenerator {
99 dtoClass : Function ,
1010 ) : string [ ] {
1111 const allowedKeys = this . getKeys ( dtoClass ) ;
12+ const activeFilters = this . collectActiveFilters ( allowedKeys , data ) ;
1213
13- // extract only key-value pairs that exist in the data and are non-null
14+ if ( activeFilters . length === 0 ) {
15+ return [ ] ;
16+ }
17+
18+ return this . buildRoomKeys ( prefix , activeFilters ) ;
19+ }
20+
21+ private static collectActiveFilters ( allowedKeys : string [ ] , data : Record < string , any > ) {
1422 const activeFilters : { key : string ; value : any } [ ] = [ ] ;
1523
1624 for ( const key of allowedKeys ) {
1725 if ( key === 'token' ) {
18- const value = data [ 'value' ] ;
19- if ( value != null && value !== '' && value !== '0' ) {
20- activeFilters . push ( { key : 'token' , value : 'EGLD' } ) ;
21- }
22- const transfers = data ?. action ?. arguments ?. transfers ;
23- if ( Array . isArray ( transfers ) ) {
24- for ( const transfer of transfers ) {
25- if ( transfer . token ) {
26- activeFilters . push ( { key : 'token' , value : transfer . token } ) ;
27- }
28- }
29- }
30- } else {
31- const value = data [ key ] ;
32- // Ignore null, undefined, and empty strings
33- if ( value !== undefined && value !== null && value !== '' ) {
34- activeFilters . push ( { key, value } ) ;
35- }
26+ this . addTokenFilters ( activeFilters , data ) ;
27+ continue ;
28+ }
29+
30+ const value = data [ key ] ;
31+ if ( this . isValidFilterValue ( value ) ) {
32+ activeFilters . push ( { key, value } ) ;
3633 }
3734 }
3835
39- if ( activeFilters . length === 0 ) {
40- return [ ] ;
36+ return activeFilters ;
37+ }
38+
39+ private static addTokenFilters ( activeFilters : { key : string ; value : any } [ ] , data : Record < string , any > ) {
40+ const value = data [ 'value' ] ;
41+ if ( this . isValidFilterValue ( value ) && value !== '0' ) {
42+ activeFilters . push ( { key : 'token' , value : 'EGLD' } ) ;
43+ }
44+
45+ const transfers = data ?. action ?. arguments ?. transfers ;
46+ if ( ! Array . isArray ( transfers ) ) {
47+ return ;
4148 }
4249
50+ for ( const transfer of transfers ) {
51+ if ( this . isValidFilterValue ( transfer ?. token ) ) {
52+ activeFilters . push ( { key : 'token' , value : transfer . token } ) ;
53+ }
54+ }
55+ }
56+
57+ private static isValidFilterValue ( value : any ) {
58+ return value !== undefined && value !== null && value !== '' ;
59+ }
60+
61+ private static buildRoomKeys ( prefix : string , activeFilters : { key : string ; value : any } [ ] ) {
4362 const rooms : string [ ] = [ ] ;
4463 const subsetCount = 1 << activeFilters . length ; // 2^N combinations
4564
46- // Generate combinatorics
4765 // Start from 1 to ignore the empty set
48- for ( let i = 1 ; i < subsetCount ; i ++ ) {
66+ for ( let mask = 1 ; mask < subsetCount ; mask ++ ) {
4967 const currentSubset : Record < string , any > = { } ;
68+ let skipIteration = false ;
5069
51- for ( let j = 0 ; j < activeFilters . length ; j ++ ) {
70+ for ( let bit = 0 ; bit < activeFilters . length ; bit ++ ) {
5271 // Check the bit to decide whether to include the element in the subset
53- if ( ( i & ( 1 << j ) ) > 0 ) {
54- const item = activeFilters [ j ] ;
72+ if ( ( mask & ( 1 << bit ) ) > 0 ) {
73+ if ( currentSubset . hasOwnProperty ( activeFilters [ bit ] . key ) ) {
74+ skipIteration = true ;
75+ continue ; // Skip duplicate keys
76+ }
77+ const item = activeFilters [ bit ] ;
5578 currentSubset [ item . key ] = item . value ;
5679 }
5780 }
58-
59- rooms . push ( `${ prefix } ${ this . deterministicStringify ( currentSubset ) } ` ) ;
81+ if ( ! skipIteration ) {
82+ rooms . push ( `${ prefix } ${ this . deterministicStringify ( currentSubset ) } ` ) ;
83+ }
6084 }
6185
6286 return rooms ;
0 commit comments