Skip to content

Commit 8ac75fb

Browse files
committed
wip: take 2 of adding selectable status
1 parent 8b1d425 commit 8ac75fb

6 files changed

Lines changed: 234 additions & 32 deletions

File tree

packages/client/src/clients/guide/client.ts

Lines changed: 87 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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

packages/client/src/clients/guide/helpers.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@ import {
99
StoreState,
1010
} from "./types";
1111

12+
type SelectionResultMetadata = {
13+
guideGroup: GuideGroupData;
14+
filters: SelectFilterParams;
15+
};
16+
1217
// Extends the map class to allow having metadata on it, which is used to record
1318
// the guide group context for the selection result (though currently only a
1419
// default global group is supported).
1520
export class SelectionResult<K = number, V = KnockGuide> extends Map<K, V> {
16-
metadata: { guideGroup: GuideGroupData } | undefined;
21+
metadata: SelectionResultMetadata | undefined;
1722

1823
constructor() {
1924
super();
@@ -233,3 +238,18 @@ export const predicateUrlPatterns = (
233238
}
234239
}, predicateDefault);
235240
};
241+
242+
// export type SelectorIdParams = {
243+
// filters: SelectFilterParams;
244+
// limit: "one" | "all";
245+
// };
246+
//
247+
// export const formatSelectorId = ({ filters, limit }: SelectorIdParams) => {
248+
//
249+
// // change to query params format
250+
// // key="asdf"&type
251+
//
252+
//
253+
// // Keep this ordering: limit, key, and type.
254+
// return JSON.stringify({ limit, key: filters.key, type: filters.type });
255+
// };

packages/client/src/clients/guide/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export {
33
DEBUG_QUERY_PARAMS,
44
checkActivatable,
55
} from "./client";
6+
export { checkStateIfThrottled } from "./helpers";
67
export type {
78
KnockGuide,
89
KnockGuideStep,
@@ -12,4 +13,5 @@ export type {
1213
SelectGuideOpts as KnockSelectGuideOpts,
1314
SelectGuidesOpts as KnockSelectGuidesOpts,
1415
StoreState as KnockGuideClientStoreState,
16+
GroupStage as KnockGuideClientGroupStage,
1517
} from "./types";

packages/client/src/clients/guide/types.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ export type SelectFilterParams = {
231231

232232
export type SelectGuideOpts = {
233233
includeThrottled?: boolean;
234+
recordSelectQuery?: boolean;
234235
};
235236

236237
export type SelectGuidesOpts = SelectGuideOpts;
@@ -247,9 +248,24 @@ export type ConstructorOpts = {
247248
throttleCheckInterval?: number;
248249
};
249250

251+
export type SelectQueryParams = SelectFilterParams & {
252+
limit: "one" | "all";
253+
};
254+
255+
type SelectGuideOptsByLimit = {
256+
one?: SelectGuideOpts;
257+
all?: SelectGuideOpts;
258+
};
259+
260+
type RecordedSelectQueries = {
261+
key?: Record<KnockGuide["key"], SelectGuideOptsByLimit>;
262+
type?: Record<KnockGuide["key"], SelectGuideOptsByLimit>;
263+
};
264+
250265
export type GroupStage = {
251266
status: "open" | "closed" | "patch";
252267
ordered: Array<KnockGuide["key"]>;
253268
resolved?: KnockGuide["key"];
269+
queries: RecordedSelectQueries;
254270
timeoutId: ReturnType<typeof setTimeout> | null;
255271
};

packages/react/src/modules/guide/components/Toolbar/V2/V2.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ const GuidesList = ({
2626
guides: InspectionResult["guides"];
2727
displayOption: DisplayOption;
2828
}) => {
29+
console.log(
30+
guides.map(
31+
(g) => g.__typename !== "MissingGuide" && g.inspection.selectable,
32+
),
33+
);
34+
2935
return guides.map((guide, idx) => {
3036
if (
3137
displayOption === "current-page" &&

0 commit comments

Comments
 (0)