@@ -46,6 +46,7 @@ import {
4646 SelectFilterParams ,
4747 SelectGuideOpts ,
4848 SelectGuidesOpts ,
49+ SelectQueryParams ,
4950 StepMessageState ,
5051 StoreState ,
5152 TargetParams ,
@@ -179,7 +180,7 @@ const select = (state: StoreState, filters: SelectFilterParams = {}) => {
179180 result . set ( index , guide ) ;
180181 }
181182
182- result . metadata = { guideGroup : defaultGroup } ;
183+ result . metadata = { guideGroup : defaultGroup , filters } ;
183184 return result ;
184185} ;
185186
@@ -613,7 +614,22 @@ export class KnockGuideClient {
613614 `[Guide] .selectGuides (filters: ${ formatFilters ( filters ) } ; state: ${ formatState ( state ) } )` ,
614615 ) ;
615616
616- const selectedGuide = this . selectGuide ( state , filters , opts ) ;
617+ const selectedGuide = this . selectGuide ( state , filters , {
618+ ...opts ,
619+ // Do not record this selectGuide() query, since this is a short to check
620+ // throttling, and we should be recording the actual selectGuides query
621+ // (as needed).
622+ recordSelectQuery : false ,
623+ } ) ;
624+
625+ // Record AFTER the selectGuide() query to ensure we have a group stage open
626+ // to be able to record.
627+ const { recordSelectQuery = ! ! state . debug ?. debugging } = opts ;
628+ this . maybeRecordSelectQuery (
629+ { ...filters , limit : "one" } ,
630+ { ...opts , recordSelectQuery } ,
631+ ) ;
632+
617633 if ( ! selectedGuide ) {
618634 return [ ] ;
619635 }
@@ -653,32 +669,6 @@ export class KnockGuideClient {
653669 return undefined ;
654670 }
655671
656- const result = select ( state , filters ) ;
657-
658- if ( result . size === 0 ) {
659- this . knock . log ( "[Guide] Selection found zero result" ) ;
660- return undefined ;
661- }
662-
663- const [ index , guide ] = [ ...result ] [ 0 ] ! ;
664- this . knock . log (
665- `[Guide] Selection found: \`${ guide . key } \` (total: ${ result . size } )` ,
666- ) ;
667-
668- // If a guide ignores the group limit, then return immediately to render
669- // always.
670- if ( guide . bypass_global_group_limit ) {
671- this . knock . log ( `[Guide] Returning the unthrottled guide: ${ guide . key } ` ) ;
672- return guide ;
673- }
674-
675- // Check if inside the throttle window (i.e. throttled) and if so stop and
676- // return undefined unless explicitly given the option to include throttled.
677- if ( ! opts . includeThrottled && checkStateIfThrottled ( state ) ) {
678- this . knock . log ( `[Guide] Throttling the selected guide: ${ guide . key } ` ) ;
679- return undefined ;
680- }
681-
682672 // Starting here to the end of this method represents the core logic of how
683673 // "group stage" works. It provides a mechanism for 1) figuring out which
684674 // guide components are about to render on a page, 2) determining which
@@ -712,6 +702,40 @@ export class KnockGuideClient {
712702 this . stage = this . openGroupStage ( ) ; // Assign here to make tsc happy
713703 }
714704
705+ // Must come AFTER we ensure a group stage exists, so we can record select
706+ // queries.
707+ const { recordSelectQuery = ! ! state . debug ?. debugging } = opts ;
708+ this . maybeRecordSelectQuery (
709+ { ...filters , limit : "one" } ,
710+ { ...opts , recordSelectQuery } ,
711+ ) ;
712+
713+ const result = select ( state , filters ) ;
714+
715+ if ( result . size === 0 ) {
716+ this . knock . log ( "[Guide] Selection found zero result" ) ;
717+ return undefined ;
718+ }
719+
720+ const [ index , guide ] = [ ...result ] [ 0 ] ! ;
721+ this . knock . log (
722+ `[Guide] Selection found: \`${ guide . key } \` (total: ${ result . size } )` ,
723+ ) ;
724+
725+ // If a guide ignores the group limit, then return immediately to render
726+ // always.
727+ if ( guide . bypass_global_group_limit ) {
728+ this . knock . log ( `[Guide] Returning the unthrottled guide: ${ guide . key } ` ) ;
729+ return guide ;
730+ }
731+
732+ // Check if inside the throttle window (i.e. throttled) and if so stop and
733+ // return undefined unless explicitly given the option to include throttled.
734+ if ( ! opts . includeThrottled && checkStateIfThrottled ( state ) ) {
735+ this . knock . log ( `[Guide] Throttling the selected guide: ${ guide . key } ` ) ;
736+ return undefined ;
737+ }
738+
715739 switch ( this . stage . status ) {
716740 case "open" : {
717741 this . knock . log ( `[Guide] Adding to the group stage: ${ guide . key } ` ) ;
@@ -740,6 +764,40 @@ export class KnockGuideClient {
740764 }
741765 }
742766
767+ private maybeRecordSelectQuery (
768+ params : SelectQueryParams ,
769+ opts : SelectGuideOpts ,
770+ ) {
771+ if ( ! opts . recordSelectQuery ) return ;
772+ if ( ! this . stage || this . stage . status === "closed" ) return ;
773+ if ( ! params . key && ! params . type ) return ;
774+
775+ // Deep merge into the query logs:
776+ const queriesByKey = this . stage . queries . key || { } ;
777+ if ( params . key ) {
778+ queriesByKey [ params . key ] = {
779+ ...( queriesByKey [ params . key ] || { } ) ,
780+ ...{ [ params . limit ] : opts } ,
781+ } ;
782+ }
783+ const queriesByType = this . stage . queries . type || { } ;
784+ if ( params . type ) {
785+ queriesByType [ params . type ] = {
786+ ...( queriesByType [ params . type ] || { } ) ,
787+ ...{ [ params . limit ] : opts } ,
788+ } ;
789+ }
790+
791+ this . stage = {
792+ ...this . stage ,
793+ queries : { key : queriesByKey , type : queriesByType } ,
794+ } ;
795+ }
796+
797+ getStage ( ) {
798+ return this . stage ;
799+ }
800+
743801 private openGroupStage ( ) {
744802 this . knock . log ( "[Guide] Opening a new group stage" ) ;
745803
@@ -755,6 +813,7 @@ export class KnockGuideClient {
755813 this . stage = {
756814 status : "open" ,
757815 ordered : [ ] ,
816+ queries : { } ,
758817 timeoutId,
759818 } ;
760819
0 commit comments