@knocklabs/client 0.19.4 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../../../src/clients/preferences/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,MAAM,6BAA6B,GAAG;IAC1C,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;KAClC,EAAE,IAAI,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,6BAA6B;CAC9D,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,6BAA6B,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,OAAO,GACP;IAAE,aAAa,EAAE,sBAAsB,CAAA;CAAE,GACzC;IAAE,QAAQ,EAAE,kBAAkB,CAAA;CAAE,GAChC,6BAA6B,CAAC;AAElC,MAAM,MAAM,mBAAmB,GAAG,OAAO,CACvC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAC1C,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,UAAU,EAAE,mBAAmB,CAAC;IAChC,aAAa,EAAE,sBAAsB,CAAC;IACtC,QAAQ,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACvC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACtC,aAAa,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC7C,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../../../src/clients/preferences/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,MAAM,6BAA6B,GAAG;IAC1C,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;KAClC,EAAE,IAAI,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,6BAA6B;CAC9D,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,6BAA6B,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,OAAO,GACP;IAAE,aAAa,EAAE,sBAAsB,CAAA;CAAE,GACzC;IAAE,QAAQ,EAAE,kBAAkB,CAAA;CAAE,GAChC,6BAA6B,CAAC;AAElC,MAAM,MAAM,mBAAmB,GAAG,OAAO,CACvC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAC1C,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACvC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACtC,aAAa,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC7C,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knocklabs/client",
3
- "version": "0.19.4",
3
+ "version": "0.20.1",
4
4
  "description": "The clientside library for interacting with Knock",
5
5
  "homepage": "https://github.com/knocklabs/javascript/tree/main/packages/client",
6
6
  "author": "@knocklabs",
@@ -9,7 +9,7 @@ import {
9
9
  DEFAULT_GROUP_KEY,
10
10
  SelectionResult,
11
11
  byKey,
12
- checkIfThrottled,
12
+ checkStateIfThrottled,
13
13
  findDefaultGroup,
14
14
  formatFilters,
15
15
  formatGroupStage,
@@ -44,6 +44,8 @@ import {
44
44
  QueryFilterParams,
45
45
  QueryStatus,
46
46
  SelectFilterParams,
47
+ SelectGuideOpts,
48
+ SelectGuidesOpts,
47
49
  StepMessageState,
48
50
  StoreState,
49
51
  TargetParams,
@@ -570,34 +572,40 @@ export class KnockGuideClient {
570
572
  selectGuides<C = Any>(
571
573
  state: StoreState,
572
574
  filters: SelectFilterParams = {},
575
+ opts: SelectGuidesOpts = {},
573
576
  ): KnockGuide<C>[] {
574
577
  this.knock.log(
575
578
  `[Guide] .selectGuides (filters: ${formatFilters(filters)}; state: ${formatState(state)})`,
576
579
  );
577
- if (
578
- Object.keys(state.guides).length === 0 &&
579
- Object.keys(state.previewGuides).length === 0
580
- ) {
581
- this.knock.log("[Guide] Exiting selection (no guides)");
580
+
581
+ const selectedGuide = this.selectGuide(state, filters, opts);
582
+ if (!selectedGuide) {
582
583
  return [];
583
584
  }
584
585
 
585
- const result = select(state, filters);
586
+ // There should be at least one guide to return here now.
587
+ const guides = [...select(state, filters).values()];
586
588
 
587
- if (result.size === 0) {
588
- this.knock.log("[Guide] Selection returned zero result");
589
- return [];
589
+ if (!opts.includeThrottled && checkStateIfThrottled(state)) {
590
+ const unthrottledGuides = guides.filter(
591
+ (g) => g.bypass_global_group_limit,
592
+ );
593
+ const throttledCount = guides.length - unthrottledGuides.length;
594
+ this.knock.log(
595
+ `[Guide] Throttling ${throttledCount} guides from selection, and returning ${unthrottledGuides.length} guides`,
596
+ );
597
+
598
+ return unthrottledGuides;
590
599
  }
591
600
 
592
- // Return all selected guides, since we cannot apply the one-at-a-time limit
593
- // or throttle settings, but rather defer to the caller to decide which ones
594
- // to render. Note
595
- return [...result.values()];
601
+ this.knock.log(`[Guide] Returning ${guides.length} guides from selection`);
602
+ return guides;
596
603
  }
597
604
 
598
605
  selectGuide<C = Any>(
599
606
  state: StoreState,
600
607
  filters: SelectFilterParams = {},
608
+ opts: SelectGuideOpts = {},
601
609
  ): KnockGuide<C> | undefined {
602
610
  this.knock.log(
603
611
  `[Guide] .selectGuide (filters: ${formatFilters(filters)}; state: ${formatState(state)})`,
@@ -630,24 +638,10 @@ export class KnockGuideClient {
630
638
  }
631
639
 
632
640
  // Check if inside the throttle window (i.e. throttled) and if so stop and
633
- // return undefined.
634
- const defaultGroup = findDefaultGroup(state.guideGroups);
635
- const throttleWindowStartedAt =
636
- state.guideGroupDisplayLogs[DEFAULT_GROUP_KEY];
637
-
638
- if (
639
- defaultGroup &&
640
- defaultGroup.display_interval &&
641
- throttleWindowStartedAt
642
- ) {
643
- const throttled = checkIfThrottled(
644
- throttleWindowStartedAt,
645
- defaultGroup.display_interval,
646
- );
647
- if (throttled) {
648
- this.knock.log(`[Guide] Throttling the selected guide: ${guide.key}`);
649
- return undefined;
650
- }
641
+ // return undefined unless explicitly given the option to include throttled.
642
+ if (!opts.includeThrottled && checkStateIfThrottled(state)) {
643
+ this.knock.log(`[Guide] Throttling the selected guide: ${guide.key}`);
644
+ return undefined;
651
645
  }
652
646
 
653
647
  // Starting here to the end of this method represents the core logic of how
@@ -814,15 +808,32 @@ export class KnockGuideClient {
814
808
  }
815
809
  }
816
810
 
817
- // Test helper that opens and closes the group stage to return the select
818
- // result immediately.
819
- private _selectGuide(state: StoreState, filters: SelectFilterParams = {}) {
811
+ // Test helpers to open and close the group stage to return the select result
812
+ // immediately.
813
+ private _selectGuide(
814
+ state: StoreState,
815
+ filters: SelectFilterParams = {},
816
+ opts: SelectGuideOpts = {},
817
+ ) {
818
+ this.openGroupStage();
819
+
820
+ this.selectGuide(state, filters, opts);
821
+ this.closePendingGroupStage();
822
+
823
+ return this.selectGuide(state, filters, opts);
824
+ }
825
+
826
+ private _selectGuides(
827
+ state: StoreState,
828
+ filters: SelectFilterParams = {},
829
+ opts: SelectGuidesOpts = {},
830
+ ) {
820
831
  this.openGroupStage();
821
832
 
822
- this.selectGuide(state, filters);
833
+ this.selectGuides(state, filters, opts);
823
834
  this.closePendingGroupStage();
824
835
 
825
- return this.selectGuide(state, filters);
836
+ return this.selectGuides(state, filters, opts);
826
837
  }
827
838
 
828
839
  //
@@ -75,11 +75,31 @@ export const findDefaultGroup = (guideGroups: GuideGroupData[]) =>
75
75
  group.key === DEFAULT_GROUP_KEY || group.key === MOCK_DEFAULT_GROUP_KEY,
76
76
  );
77
77
 
78
+ export const checkStateIfThrottled = (state: StoreState) => {
79
+ const defaultGroup = findDefaultGroup(state.guideGroups);
80
+ const throttleWindowStartedAt =
81
+ state.guideGroupDisplayLogs[DEFAULT_GROUP_KEY];
82
+
83
+ if (
84
+ defaultGroup &&
85
+ defaultGroup.display_interval &&
86
+ throttleWindowStartedAt
87
+ ) {
88
+ return checkTimeIfThrottled(
89
+ throttleWindowStartedAt,
90
+ defaultGroup.display_interval,
91
+ );
92
+ }
93
+
94
+ // Fall back to false, though this should never happen.
95
+ return false;
96
+ };
97
+
78
98
  // Checks whether we are currently throttled (inside a "throttle window").
79
99
  // A throttle window opens when a user dismisses (archives) a guide, and lasts
80
100
  // for the configured display interval of the guide group used (currently only
81
101
  // the default global group).
82
- export const checkIfThrottled = (
102
+ const checkTimeIfThrottled = (
83
103
  throttleWindowStartedAtTs: string,
84
104
  windowDurationInSeconds: number,
85
105
  ) => {
@@ -4,4 +4,6 @@ export type {
4
4
  KnockGuideStep,
5
5
  TargetParams as KnockGuideTargetParams,
6
6
  SelectFilterParams as KnockGuideFilterParams,
7
+ SelectGuideOpts as KnockSelectGuideOpts,
8
+ SelectGuidesOpts as KnockSelectGuidesOpts,
7
9
  } from "./types";
@@ -212,6 +212,12 @@ export type SelectFilterParams = {
212
212
  type?: string;
213
213
  };
214
214
 
215
+ export type SelectGuideOpts = {
216
+ includeThrottled?: boolean;
217
+ };
218
+
219
+ export type SelectGuidesOpts = SelectGuideOpts;
220
+
215
221
  export type TargetParams = {
216
222
  data?: GenericData | undefined;
217
223
  tenant?: string | undefined;
@@ -23,10 +23,10 @@ export type WorkflowPreferences = Partial<
23
23
  >;
24
24
 
25
25
  export interface SetPreferencesProperties {
26
- workflows: WorkflowPreferences;
27
- categories: WorkflowPreferences;
28
- channel_types: ChannelTypePreferences;
29
- channels: ChannelPreferences;
26
+ workflows?: WorkflowPreferences;
27
+ categories?: WorkflowPreferences;
28
+ channel_types?: ChannelTypePreferences;
29
+ channels?: ChannelPreferences;
30
30
  }
31
31
 
32
32
  export interface PreferenceSet {