@@ -46,6 +46,7 @@ import {
4646 SelectFilterParams ,
4747 SelectGuideOpts ,
4848 SelectGuidesOpts ,
49+ SelectQueryParams ,
4950 StepMessageState ,
5051 StoreState ,
5152 TargetParams ,
@@ -175,7 +176,7 @@ const select = (state: StoreState, filters: SelectFilterParams = {}) => {
175176 result . set ( index , guide ) ;
176177 }
177178
178- result . metadata = { guideGroup : defaultGroup } ;
179+ result . metadata = { guideGroup : defaultGroup , filters } ;
179180 return result ;
180181} ;
181182
@@ -617,7 +618,22 @@ export class KnockGuideClient {
617618 `[Guide] .selectGuides (filters: ${ formatFilters ( filters ) } ; state: ${ formatState ( state ) } )` ,
618619 ) ;
619620
620- const selectedGuide = this . selectGuide ( state , filters , opts ) ;
621+ const selectedGuide = this . selectGuide ( state , filters , {
622+ ...opts ,
623+ // Do not record this selectGuide() query, since this is a short to check
624+ // throttling, and we should be recording the actual selectGuides query
625+ // (as needed).
626+ recordSelectQuery : false ,
627+ } ) ;
628+
629+ // Record AFTER the selectGuide() query to ensure we have a group stage open
630+ // to be able to record.
631+ const { recordSelectQuery = ! ! state . debug ?. debugging } = opts ;
632+ this . maybeRecordSelectQuery (
633+ { ...filters , limit : "one" } ,
634+ { ...opts , recordSelectQuery } ,
635+ ) ;
636+
621637 if ( ! selectedGuide ) {
622638 return [ ] ;
623639 }
@@ -657,32 +673,6 @@ export class KnockGuideClient {
657673 return undefined ;
658674 }
659675
660- const result = select ( state , filters ) ;
661-
662- if ( result . size === 0 ) {
663- this . knock . log ( "[Guide] Selection found zero result" ) ;
664- return undefined ;
665- }
666-
667- const [ index , guide ] = [ ...result ] [ 0 ] ! ;
668- this . knock . log (
669- `[Guide] Selection found: \`${ guide . key } \` (total: ${ result . size } )` ,
670- ) ;
671-
672- // If a guide ignores the group limit, then return immediately to render
673- // always.
674- if ( guide . bypass_global_group_limit ) {
675- this . knock . log ( `[Guide] Returning the unthrottled guide: ${ guide . key } ` ) ;
676- return guide ;
677- }
678-
679- // Check if inside the throttle window (i.e. throttled) and if so stop and
680- // return undefined unless explicitly given the option to include throttled.
681- if ( ! opts . includeThrottled && checkStateIfThrottled ( state ) ) {
682- this . knock . log ( `[Guide] Throttling the selected guide: ${ guide . key } ` ) ;
683- return undefined ;
684- }
685-
686676 // Starting here to the end of this method represents the core logic of how
687677 // "group stage" works. It provides a mechanism for 1) figuring out which
688678 // guide components are about to render on a page, 2) determining which
@@ -716,6 +706,40 @@ export class KnockGuideClient {
716706 this . stage = this . openGroupStage ( ) ; // Assign here to make tsc happy
717707 }
718708
709+ // Must come AFTER we ensure a group stage exists, so we can record select
710+ // queries.
711+ const { recordSelectQuery = ! ! state . debug ?. debugging } = opts ;
712+ this . maybeRecordSelectQuery (
713+ { ...filters , limit : "one" } ,
714+ { ...opts , recordSelectQuery } ,
715+ ) ;
716+
717+ const result = select ( state , filters ) ;
718+
719+ if ( result . size === 0 ) {
720+ this . knock . log ( "[Guide] Selection found zero result" ) ;
721+ return undefined ;
722+ }
723+
724+ const [ index , guide ] = [ ...result ] [ 0 ] ! ;
725+ this . knock . log (
726+ `[Guide] Selection found: \`${ guide . key } \` (total: ${ result . size } )` ,
727+ ) ;
728+
729+ // If a guide ignores the group limit, then return immediately to render
730+ // always.
731+ if ( guide . bypass_global_group_limit ) {
732+ this . knock . log ( `[Guide] Returning the unthrottled guide: ${ guide . key } ` ) ;
733+ return guide ;
734+ }
735+
736+ // Check if inside the throttle window (i.e. throttled) and if so stop and
737+ // return undefined unless explicitly given the option to include throttled.
738+ if ( ! opts . includeThrottled && checkStateIfThrottled ( state ) ) {
739+ this . knock . log ( `[Guide] Throttling the selected guide: ${ guide . key } ` ) ;
740+ return undefined ;
741+ }
742+
719743 switch ( this . stage . status ) {
720744 case "open" : {
721745 this . knock . log ( `[Guide] Adding to the group stage: ${ guide . key } ` ) ;
@@ -744,6 +768,40 @@ export class KnockGuideClient {
744768 }
745769 }
746770
771+ private maybeRecordSelectQuery (
772+ params : SelectQueryParams ,
773+ opts : SelectGuideOpts ,
774+ ) {
775+ if ( ! opts . recordSelectQuery ) return ;
776+ if ( ! this . stage || this . stage . status === "closed" ) return ;
777+ if ( ! params . key && ! params . type ) return ;
778+
779+ // Deep merge into the query logs:
780+ const queriesByKey = this . stage . queries . key || { } ;
781+ if ( params . key ) {
782+ queriesByKey [ params . key ] = {
783+ ...( queriesByKey [ params . key ] || { } ) ,
784+ ...{ [ params . limit ] : opts } ,
785+ } ;
786+ }
787+ const queriesByType = this . stage . queries . type || { } ;
788+ if ( params . type ) {
789+ queriesByType [ params . type ] = {
790+ ...( queriesByType [ params . type ] || { } ) ,
791+ ...{ [ params . limit ] : opts } ,
792+ } ;
793+ }
794+
795+ this . stage = {
796+ ...this . stage ,
797+ queries : { key : queriesByKey , type : queriesByType } ,
798+ } ;
799+ }
800+
801+ getStage ( ) {
802+ return this . stage ;
803+ }
804+
747805 private openGroupStage ( ) {
748806 this . knock . log ( "[Guide] Opening a new group stage" ) ;
749807
@@ -759,6 +817,7 @@ export class KnockGuideClient {
759817 this . stage = {
760818 status : "open" ,
761819 ordered : [ ] ,
820+ queries : { } ,
762821 timeoutId,
763822 } ;
764823
0 commit comments