@knocklabs/client 0.21.0 → 0.21.2

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/api.js +1 -1
  3. package/dist/cjs/api.js.map +1 -1
  4. package/dist/cjs/clients/feed/feed.js +1 -1
  5. package/dist/cjs/clients/feed/feed.js.map +1 -1
  6. package/dist/cjs/clients/feed/utils.js.map +1 -1
  7. package/dist/cjs/clients/guide/client.js +1 -1
  8. package/dist/cjs/clients/guide/client.js.map +1 -1
  9. package/dist/cjs/clients/guide/helpers.js +1 -1
  10. package/dist/cjs/clients/guide/helpers.js.map +1 -1
  11. package/dist/cjs/clients/guide/types.js +2 -0
  12. package/dist/cjs/clients/guide/types.js.map +1 -0
  13. package/dist/cjs/helpers.js +1 -1
  14. package/dist/cjs/helpers.js.map +1 -1
  15. package/dist/cjs/index.js +1 -1
  16. package/dist/cjs/knock.js +2 -2
  17. package/dist/cjs/knock.js.map +1 -1
  18. package/dist/cjs/pageVisibility.js +2 -0
  19. package/dist/cjs/pageVisibility.js.map +1 -0
  20. package/dist/esm/api.mjs +27 -12
  21. package/dist/esm/api.mjs.map +1 -1
  22. package/dist/esm/clients/feed/feed.mjs +60 -87
  23. package/dist/esm/clients/feed/feed.mjs.map +1 -1
  24. package/dist/esm/clients/feed/utils.mjs.map +1 -1
  25. package/dist/esm/clients/guide/client.mjs +270 -204
  26. package/dist/esm/clients/guide/client.mjs.map +1 -1
  27. package/dist/esm/clients/guide/helpers.mjs +34 -44
  28. package/dist/esm/clients/guide/helpers.mjs.map +1 -1
  29. package/dist/esm/clients/guide/types.mjs +13 -0
  30. package/dist/esm/clients/guide/types.mjs.map +1 -0
  31. package/dist/esm/helpers.mjs +19 -4
  32. package/dist/esm/helpers.mjs.map +1 -1
  33. package/dist/esm/index.mjs +13 -10
  34. package/dist/esm/index.mjs.map +1 -1
  35. package/dist/esm/knock.mjs +31 -29
  36. package/dist/esm/knock.mjs.map +1 -1
  37. package/dist/esm/pageVisibility.mjs +31 -0
  38. package/dist/esm/pageVisibility.mjs.map +1 -0
  39. package/dist/types/api.d.ts +4 -0
  40. package/dist/types/api.d.ts.map +1 -1
  41. package/dist/types/clients/feed/feed.d.ts +1 -11
  42. package/dist/types/clients/feed/feed.d.ts.map +1 -1
  43. package/dist/types/clients/feed/interfaces.d.ts +15 -5
  44. package/dist/types/clients/feed/interfaces.d.ts.map +1 -1
  45. package/dist/types/clients/feed/utils.d.ts +0 -2
  46. package/dist/types/clients/feed/utils.d.ts.map +1 -1
  47. package/dist/types/clients/guide/client.d.ts +6 -1
  48. package/dist/types/clients/guide/client.d.ts.map +1 -1
  49. package/dist/types/clients/guide/helpers.d.ts +1 -7
  50. package/dist/types/clients/guide/helpers.d.ts.map +1 -1
  51. package/dist/types/clients/guide/index.d.ts +3 -2
  52. package/dist/types/clients/guide/index.d.ts.map +1 -1
  53. package/dist/types/clients/guide/types.d.ts +33 -1
  54. package/dist/types/clients/guide/types.d.ts.map +1 -1
  55. package/dist/types/helpers.d.ts +19 -0
  56. package/dist/types/helpers.d.ts.map +1 -1
  57. package/dist/types/interfaces.d.ts +2 -0
  58. package/dist/types/interfaces.d.ts.map +1 -1
  59. package/dist/types/knock.d.ts +1 -0
  60. package/dist/types/knock.d.ts.map +1 -1
  61. package/dist/types/pageVisibility.d.ts +22 -0
  62. package/dist/types/pageVisibility.d.ts.map +1 -0
  63. package/package.json +2 -2
  64. package/src/api.ts +30 -0
  65. package/src/clients/feed/feed.ts +0 -73
  66. package/src/clients/feed/interfaces.ts +15 -11
  67. package/src/clients/feed/utils.ts +11 -2
  68. package/src/clients/guide/client.ts +206 -84
  69. package/src/clients/guide/helpers.ts +0 -12
  70. package/src/clients/guide/index.ts +10 -1
  71. package/src/clients/guide/types.ts +55 -1
  72. package/src/helpers.ts +39 -0
  73. package/src/interfaces.ts +2 -0
  74. package/src/knock.ts +4 -3
  75. package/src/pageVisibility.ts +70 -0
@@ -1,30 +1,31 @@
1
- var _ = Object.defineProperty;
2
- var b = (u, e, t) => e in u ? _(u, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[e] = t;
3
- var d = (u, e, t) => b(u, typeof e != "symbol" ? e + "" : e, t);
4
- import { Store as I } from "@tanstack/store";
5
- import { URLPattern as C } from "urlpattern-polyfill";
6
- import { byKey as E, mockDefaultGroup as w, formatFilters as f, formatState as G, checkStateIfThrottled as S, formatGroupStage as y, DEFAULT_GROUP_KEY as R, SelectionResult as P, findDefaultGroup as A, newUrl as L, predicateUrlRules as D, predicateUrlPatterns as K } from "./helpers.mjs";
7
- const $ = 50, T = 30 * 1e3, O = 3, g = {
1
+ var I = Object.defineProperty;
2
+ var C = (u, e, t) => e in u ? I(u, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[e] = t;
3
+ var l = (u, e, t) => C(u, typeof e != "symbol" ? e + "" : e, t);
4
+ import { Store as E } from "@tanstack/store";
5
+ import { URLPattern as w } from "urlpattern-polyfill";
6
+ import { byKey as y, mockDefaultGroup as R, formatFilters as G, formatState as S, checkStateIfThrottled as m, formatGroupStage as v, DEFAULT_GROUP_KEY as P, newUrl as D, predicateUrlRules as A, predicateUrlPatterns as L, findDefaultGroup as T } from "./helpers.mjs";
7
+ import { SelectionResult as $ } from "./types.mjs";
8
+ const K = 50, O = 30 * 1e3, U = 3, p = {
8
9
  GUIDE_KEY: "knock_guide_key",
9
10
  PREVIEW_SESSION_ID: "knock_preview_session_id"
10
- }, k = "knock_guide_debug", l = () => {
11
+ }, f = "knock_guide_debug", k = () => {
11
12
  if (typeof window < "u")
12
13
  return window;
13
- }, U = (u) => `/v1/users/${u}/guides`, m = () => {
14
- const u = l();
14
+ }, F = (u) => `/v1/users/${u}/guides`, b = () => {
15
+ const u = k();
15
16
  if (!u || !u.location)
16
17
  return { forcedGuideKey: null, previewSessionId: null };
17
- const e = new URLSearchParams(u.location.search), t = e.get(g.GUIDE_KEY), s = e.get(
18
- g.PREVIEW_SESSION_ID
18
+ const e = new URLSearchParams(u.location.search), t = e.get(p.GUIDE_KEY), s = e.get(
19
+ p.PREVIEW_SESSION_ID
19
20
  );
20
21
  if (t || s) {
21
22
  if (u.localStorage)
22
23
  try {
23
- const i = {
24
+ const r = {
24
25
  forcedGuideKey: t,
25
26
  previewSessionId: s
26
27
  };
27
- u.localStorage.setItem(k, JSON.stringify(i));
28
+ u.localStorage.setItem(f, JSON.stringify(r));
28
29
  } catch {
29
30
  }
30
31
  return {
@@ -32,21 +33,21 @@ const $ = 50, T = 30 * 1e3, O = 3, g = {
32
33
  previewSessionId: s
33
34
  };
34
35
  }
35
- let r = null, n = null;
36
+ let i = null, n = null;
36
37
  if (u.localStorage)
37
38
  try {
38
- const i = u.localStorage.getItem(k);
39
- if (i) {
40
- const o = F(i);
41
- r = o.forcedGuideKey, n = o.previewSessionId;
39
+ const r = u.localStorage.getItem(f);
40
+ if (r) {
41
+ const a = q(r);
42
+ i = a.forcedGuideKey, n = a.previewSessionId;
42
43
  }
43
44
  } catch {
44
45
  }
45
46
  return {
46
- forcedGuideKey: r,
47
+ forcedGuideKey: i,
47
48
  previewSessionId: n
48
49
  };
49
- }, F = (u) => {
50
+ }, q = (u) => {
50
51
  try {
51
52
  const e = JSON.parse(u);
52
53
  return {
@@ -59,45 +60,35 @@ const $ = 50, T = 30 * 1e3, O = 3, g = {
59
60
  previewSessionId: null
60
61
  };
61
62
  }
62
- }, v = (u, e = {}) => {
63
- const t = new P(), s = A(u.guideGroups);
64
- if (!s) return t;
65
- const r = [...s.display_sequence], n = u.location;
66
- if (u.debug.forcedGuideKey) {
67
- const i = r.indexOf(u.debug.forcedGuideKey);
68
- i > -1 && r.splice(i, 1), r.unshift(u.debug.forcedGuideKey);
69
- }
70
- for (const [i, o] of r.entries()) {
71
- let a = u.guides[o];
72
- u.debug.forcedGuideKey === o && u.previewGuides[o] && (a = u.previewGuides[o]), !(!a || !N(a, {
73
- location: n,
74
- filters: e,
63
+ }, _ = (u, e, t) => {
64
+ const s = new $(), i = T(u.guideGroups);
65
+ if (!i) return s;
66
+ const n = i.display_sequence, r = u.location;
67
+ for (const [a, o] of n.entries()) {
68
+ const c = u.previewGuides[o] || u.guides[o];
69
+ !c || !N(c, e, {
70
+ location: r,
71
+ ineligibleGuides: u.ineligibleGuides,
75
72
  debug: u.debug
76
- })) && t.set(i, a);
77
- }
78
- return t.metadata = { guideGroup: s }, t;
79
- }, N = (u, { location: e, filters: t = {}, debug: s = {} }) => {
80
- if (t.type && t.type !== u.type || t.key && t.key !== u.key)
81
- return !1;
82
- if (s.forcedGuideKey === u.key)
83
- return !0;
84
- if (!u.active || u.steps.every((o) => !!o.message.archived_at))
85
- return !1;
86
- const r = e ? L(e) : void 0, n = u.activation_url_rules || [], i = u.activation_url_patterns || [];
87
- if (r && n.length > 0) {
88
- if (!D(r, n)) return !1;
89
- } else if (r && i.length > 0 && !K(r, i))
73
+ }) || s.set(a, c);
74
+ }
75
+ return s.metadata = { guideGroup: i, filters: e, ...t }, s;
76
+ }, N = (u, e, { location: t, ineligibleGuides: s = {}, debug: i = {} }) => e.type && e.type !== u.type || e.key && e.key !== u.key ? !1 : i.forcedGuideKey ? i.forcedGuideKey === u.key : s[u.key] || !u.active || u.steps.every((r) => !!r.message.archived_at) ? !1 : j(u, t), j = (u, e) => {
77
+ const t = e ? D(e) : void 0, s = u.activation_url_rules || [], i = u.activation_url_patterns || [];
78
+ if (t && s.length > 0) {
79
+ if (!A(t, s)) return !1;
80
+ } else if (t && i.length > 0 && !L(t, i))
90
81
  return !1;
91
82
  return !0;
92
83
  };
93
- class B {
94
- constructor(e, t, s = {}, r = {}) {
95
- d(this, "store");
84
+ class W {
85
+ constructor(e, t, s = {}, i = {}) {
86
+ l(this, "store");
96
87
  // Phoenix channels for real time guide updates over websocket
97
- d(this, "socket");
98
- d(this, "socketChannel");
99
- d(this, "socketChannelTopic");
100
- d(this, "socketEventTypes", [
88
+ l(this, "socket");
89
+ l(this, "socketChannel");
90
+ l(this, "socketChannelTopic");
91
+ l(this, "socketEventTypes", [
101
92
  "guide.added",
102
93
  "guide.updated",
103
94
  "guide.removed",
@@ -105,50 +96,57 @@ class B {
105
96
  "guide_group.updated",
106
97
  "guide.live_preview_updated"
107
98
  ]);
108
- d(this, "subscribeRetryCount", 0);
99
+ l(this, "subscribeRetryCount", 0);
109
100
  // Original history methods to monkey patch, or restore in cleanups.
110
- d(this, "pushStateFn");
111
- d(this, "replaceStateFn");
101
+ l(this, "pushStateFn");
102
+ l(this, "replaceStateFn");
112
103
  // Guides that are competing to render are "staged" first without rendering
113
104
  // and ranked based on its relative order in the group over a duration of time
114
105
  // to resolve and render the prevailing one.
115
- d(this, "stage");
116
- d(this, "counterIntervalId");
106
+ l(this, "stage");
107
+ l(this, "counterIntervalId");
117
108
  // Define as an arrow func property to always bind this to the class instance.
118
- d(this, "handleLocationChange", () => {
109
+ l(this, "handleLocationChange", () => {
119
110
  this.knock.log("[Guide] .handleLocationChange");
120
- const e = l();
111
+ const e = k();
121
112
  if (!(e != null && e.location)) return;
122
113
  const t = e.location.href;
123
114
  if (this.store.state.location === t) return;
124
- this.knock.log(`[Guide] Detected a location change: ${t}`);
125
- const s = this.store.state.debug, r = m();
126
- this.setLocation(t, { debug: r }), this.checkDebugStateChanged(
115
+ if (this.knock.log(`[Guide] Detected a location change: ${t}`), !this.options.trackDebugParams) {
116
+ this.setLocation(t);
117
+ return;
118
+ }
119
+ const s = this.store.state.debug || {}, i = b();
120
+ this.setLocation(t, { debug: i }), this.checkDebugStateChanged(
127
121
  s,
128
- r
122
+ i
129
123
  ) && (this.knock.log(
130
124
  "[Guide] Debug state changed, refetching guides and resubscribing to the websocket channel"
131
125
  ), this.fetch(), this.subscribe());
132
126
  });
133
- var p;
134
- this.knock = e, this.channelId = t, this.targetParams = s, this.options = r;
127
+ var g;
128
+ this.knock = e, this.channelId = t, this.targetParams = s, this.options = i;
135
129
  const {
136
130
  trackLocationFromWindow: n = !0,
137
- throttleCheckInterval: i = T
138
- } = r, o = l(), a = n ? (p = o == null ? void 0 : o.location) == null ? void 0 : p.href : void 0, h = m();
139
- this.store = new I({
131
+ // TODO(KNO-11523): Remove once we ship guide toolbar v2, and offload as
132
+ // much debugging specific logic and responsibilities to toolbar.
133
+ trackDebugParams: r = !1,
134
+ throttleCheckInterval: a = O
135
+ } = i, o = k(), c = n ? (g = o == null ? void 0 : o.location) == null ? void 0 : g.href : void 0, d = r ? b() : void 0;
136
+ this.store = new E({
140
137
  guideGroups: [],
141
138
  guideGroupDisplayLogs: {},
142
139
  guides: {},
140
+ ineligibleGuides: {},
143
141
  previewGuides: {},
144
142
  queries: {},
145
- location: a,
143
+ location: c,
146
144
  // Increment to update the state store and trigger re-selection.
147
145
  counter: 0,
148
- debug: h
146
+ debug: d
149
147
  });
150
- const { socket: c } = this.knock.client();
151
- this.socket = c, this.socketChannelTopic = `guides:${t}`, n && this.listenForLocationChangesFromWindow(), i && this.startCounterInterval(i), this.knock.log("[Guide] Initialized a guide client");
148
+ const { socket: h } = this.knock.client();
149
+ this.socket = h, this.socketChannelTopic = `guides:${t}`, n && this.listenForLocationChangesFromWindow(), a && this.startCounterInterval(a), this.knock.log("[Guide] Initialized a guide client");
152
150
  }
153
151
  incrementCounter() {
154
152
  this.knock.log("[Guide] Incrementing the counter"), this.store.setState((e) => ({ ...e, counter: e.counter + 1 }));
@@ -166,30 +164,36 @@ class B {
166
164
  }
167
165
  async fetch(e) {
168
166
  this.knock.log("[Guide] .fetch"), this.knock.failIfNotAuthenticated();
169
- const t = this.buildQueryParams(e == null ? void 0 : e.filters), s = this.formatQueryKey(t), r = this.store.state.queries[s];
170
- if (r)
171
- return r;
172
- this.store.setState((i) => ({
173
- ...i,
174
- queries: { ...i.queries, [s]: { status: "loading" } }
167
+ const t = this.buildQueryParams(e == null ? void 0 : e.filters), s = this.formatQueryKey(t), i = this.store.state.queries[s];
168
+ if (i)
169
+ return i;
170
+ this.store.setState((r) => ({
171
+ ...r,
172
+ queries: { ...r.queries, [s]: { status: "loading" } }
175
173
  }));
176
174
  let n;
177
175
  try {
178
176
  this.knock.log("[Guide] Fetching all eligible guides");
179
- const i = await this.knock.user.getGuides(this.channelId, t);
177
+ const r = await this.knock.user.getGuides(this.channelId, t);
180
178
  n = { status: "ok" };
181
- const { entries: o, guide_groups: a, guide_group_display_logs: h } = i;
182
- this.knock.log("[Guide] Loading fetched guides"), this.store.setState((c) => ({
183
- ...c,
184
- guideGroups: (a == null ? void 0 : a.length) > 0 ? a : [w(o)],
185
- guideGroupDisplayLogs: h || {},
186
- guides: E(o.map((p) => this.localCopy(p))),
187
- queries: { ...c.queries, [s]: n }
179
+ const {
180
+ entries: a,
181
+ guide_groups: o,
182
+ guide_group_display_logs: c,
183
+ ineligible_guides: d
184
+ } = r;
185
+ this.knock.log("[Guide] Loading fetched guides"), this.store.setState((h) => ({
186
+ ...h,
187
+ guideGroups: (o == null ? void 0 : o.length) > 0 ? o : [R(a)],
188
+ guideGroupDisplayLogs: c || {},
189
+ guides: y(a.map((g) => this.localCopy(g))),
190
+ ineligibleGuides: y(d || []),
191
+ queries: { ...h.queries, [s]: n }
188
192
  }));
189
- } catch (i) {
190
- n = { status: "error", error: i }, this.store.setState((o) => ({
191
- ...o,
192
- queries: { ...o.queries, [s]: n }
193
+ } catch (r) {
194
+ n = { status: "error", error: r }, this.store.setState((a) => ({
195
+ ...a,
196
+ queries: { ...a.queries, [s]: n }
193
197
  }));
194
198
  }
195
199
  return n;
@@ -200,23 +204,23 @@ class B {
200
204
  const e = this.store.state.debug, t = {
201
205
  ...this.targetParams,
202
206
  user_id: this.knock.userId,
203
- force_all_guides: e.forcedGuideKey ? !0 : void 0,
204
- preview_session_id: e.previewSessionId || void 0
207
+ force_all_guides: e != null && e.forcedGuideKey || e != null && e.debugging ? !0 : void 0,
208
+ preview_session_id: (e == null ? void 0 : e.previewSessionId) || void 0
205
209
  }, s = this.socket.channel(this.socketChannelTopic, t);
206
- for (const r of this.socketEventTypes)
207
- s.on(r, (n) => this.handleSocketEvent(n));
210
+ for (const i of this.socketEventTypes)
211
+ s.on(i, (n) => this.handleSocketEvent(n));
208
212
  ["closed", "errored"].includes(s.state) && (this.subscribeRetryCount = 0, s.join().receive("ok", () => {
209
213
  this.knock.log("[Guide] Successfully joined channel");
210
- }).receive("error", (r) => {
214
+ }).receive("error", (i) => {
211
215
  this.knock.log(
212
- `[Guide] Failed to join channel: ${JSON.stringify(r)}`
216
+ `[Guide] Failed to join channel: ${JSON.stringify(i)}`
213
217
  ), this.handleChannelJoinError();
214
218
  }).receive("timeout", () => {
215
219
  this.knock.log("[Guide] Channel join timed out"), this.handleChannelJoinError();
216
220
  })), this.socketChannel = s;
217
221
  }
218
222
  handleChannelJoinError() {
219
- if (this.subscribeRetryCount >= O) {
223
+ if (this.subscribeRetryCount >= U) {
220
224
  this.knock.log(
221
225
  `[Guide] Channel join max retry limit reached: ${this.subscribeRetryCount}`
222
226
  ), this.unsubscribe();
@@ -253,21 +257,21 @@ class B {
253
257
  setLocation(e, t = {}) {
254
258
  this.knock.log(`[Guide] .setLocation (loc=${e})`), this.clearGroupStage(), this.knock.log("[Guide] Updating the tracked location"), this.store.setState((s) => {
255
259
  var n;
256
- const r = (n = t == null ? void 0 : t.debug) != null && n.previewSessionId ? s.previewGuides : {};
260
+ const i = (n = t == null ? void 0 : t.debug) != null && n.previewSessionId ? s.previewGuides : {};
257
261
  return {
258
262
  ...s,
259
263
  ...t,
260
- previewGuides: r,
264
+ previewGuides: i,
261
265
  location: e
262
266
  };
263
267
  });
264
268
  }
265
269
  exitDebugMode() {
266
270
  this.knock.log("[Guide] Exiting debug mode");
267
- const e = l();
271
+ const e = k();
268
272
  if (e != null && e.localStorage)
269
273
  try {
270
- e.localStorage.removeItem(k);
274
+ e.localStorage.removeItem(f);
271
275
  } catch {
272
276
  }
273
277
  if (this.store.setState((t) => ({
@@ -277,79 +281,141 @@ class B {
277
281
  // Clear preview guides when exiting debug mode
278
282
  })), e != null && e.location) {
279
283
  const t = new URL(e.location.href);
280
- (t.searchParams.has(g.GUIDE_KEY) || t.searchParams.has(g.PREVIEW_SESSION_ID)) && (t.searchParams.delete(g.GUIDE_KEY), t.searchParams.delete(g.PREVIEW_SESSION_ID), e.location.href = t.toString());
284
+ (t.searchParams.has(p.GUIDE_KEY) || t.searchParams.has(p.PREVIEW_SESSION_ID)) && (t.searchParams.delete(p.GUIDE_KEY), t.searchParams.delete(p.PREVIEW_SESSION_ID), e.location.href = t.toString());
281
285
  }
282
286
  }
287
+ setDebug(e) {
288
+ var s;
289
+ this.knock.log("[Guide] .setDebug()");
290
+ const t = !((s = this.store.state.debug) != null && s.debugging);
291
+ this.store.setState((i) => ({
292
+ ...i,
293
+ debug: { ...e, debugging: !0 }
294
+ })), t && (this.knock.log(
295
+ "[Guide] Start debugging, refetching guides and resubscribing to the websocket channel"
296
+ ), this.fetch(), this.subscribe());
297
+ }
298
+ unsetDebug() {
299
+ var t;
300
+ this.knock.log("[Guide] .unsetDebug()");
301
+ const e = (t = this.store.state.debug) == null ? void 0 : t.debugging;
302
+ this.store.setState((s) => ({ ...s, debug: void 0 })), e && (this.knock.log(
303
+ "[Guide] Stop debugging, refetching guides and resubscribing to the websocket channel"
304
+ ), this.fetch(), this.subscribe());
305
+ }
283
306
  //
284
307
  // Store selector
285
308
  //
286
309
  selectGuides(e, t = {}, s = {}) {
287
- if (this.knock.log(
288
- `[Guide] .selectGuides (filters: ${f(t)}; state: ${G(e)})`
289
- ), !this.selectGuide(e, t, s))
310
+ var c;
311
+ this.knock.log(
312
+ `[Guide] .selectGuides (filters: ${G(t)}; state: ${S(e)})`
313
+ );
314
+ const i = this.selectGuide(e, t, {
315
+ ...s,
316
+ // Don't record this result, not the actual query result we need.
317
+ recordSelectQuery: !1
318
+ }), { recordSelectQuery: n = !!((c = e.debug) != null && c.debugging) } = s, r = {
319
+ limit: "all",
320
+ opts: { ...s, recordSelectQuery: n }
321
+ }, a = _(e, t, r);
322
+ if (this.maybeRecordSelectResult(a), !i && !s.includeThrottled)
290
323
  return [];
291
- const n = [...v(e, t).values()];
292
- if (!s.includeThrottled && S(e)) {
293
- const i = n.filter(
294
- (a) => a.bypass_global_group_limit
295
- ), o = n.length - i.length;
324
+ const o = [...a.values()];
325
+ if (!s.includeThrottled && m(e)) {
326
+ const d = o.filter(
327
+ (g) => g.bypass_global_group_limit
328
+ ), h = o.length - d.length;
296
329
  return this.knock.log(
297
- `[Guide] Throttling ${o} guides from selection, and returning ${i.length} guides`
298
- ), i;
330
+ `[Guide] Throttling ${h} guides from selection, and returning ${d.length} guides`
331
+ ), d;
299
332
  }
300
- return this.knock.log(`[Guide] Returning ${n.length} guides from selection`), n;
333
+ return this.knock.log(`[Guide] Returning ${o.length} guides from selection`), o;
301
334
  }
302
335
  selectGuide(e, t = {}, s = {}) {
336
+ var d;
303
337
  if (this.knock.log(
304
- `[Guide] .selectGuide (filters: ${f(t)}; state: ${G(e)})`
338
+ `[Guide] .selectGuide (filters: ${G(t)}; state: ${S(e)})`
305
339
  ), Object.keys(e.guides).length === 0 && Object.keys(e.previewGuides).length === 0) {
306
340
  this.knock.log("[Guide] Exiting selection (no guides)");
307
341
  return;
308
342
  }
309
- const r = v(e, t);
310
- if (r.size === 0) {
343
+ this.stage || (this.stage = this.openGroupStage());
344
+ const { recordSelectQuery: i = !!((d = e.debug) != null && d.debugging) } = s, n = {
345
+ limit: "one",
346
+ opts: { ...s, recordSelectQuery: i }
347
+ }, r = _(e, t, n);
348
+ if (this.maybeRecordSelectResult(r), r.size === 0) {
311
349
  this.knock.log("[Guide] Selection found zero result");
312
350
  return;
313
351
  }
314
- const [n, i] = [...r][0];
352
+ const [a, o] = [...r][0];
315
353
  if (this.knock.log(
316
- `[Guide] Selection found: \`${i.key}\` (total: ${r.size})`
317
- ), i.bypass_global_group_limit)
318
- return this.knock.log(`[Guide] Returning the unthrottled guide: ${i.key}`), i;
319
- if (!s.includeThrottled && S(e)) {
320
- this.knock.log(`[Guide] Throttling the selected guide: ${i.key}`);
321
- return;
322
- }
323
- switch (this.stage || (this.stage = this.openGroupStage()), this.stage.status) {
354
+ `[Guide] Selection found: \`${o.key}\` (total: ${r.size})`
355
+ ), o.bypass_global_group_limit)
356
+ return this.knock.log(`[Guide] Returning the unthrottled guide: ${o.key}`), o;
357
+ const c = !s.includeThrottled && m(e);
358
+ switch (this.stage.status) {
324
359
  case "open": {
325
- this.knock.log(`[Guide] Adding to the group stage: ${i.key}`), this.stage.ordered[n] = i.key;
360
+ this.knock.log(`[Guide] Adding to the group stage: ${o.key}`), this.stage.ordered[a] = o.key;
326
361
  return;
327
362
  }
328
363
  case "patch": {
329
- this.knock.log(`[Guide] Patching the group stage: ${i.key}`), this.stage.ordered[n] = i.key;
330
- const o = this.stage.resolved === i.key ? i : void 0;
364
+ if (this.knock.log(`[Guide] Patching the group stage: ${o.key}`), this.stage.ordered[a] = o.key, c) {
365
+ this.knock.log(`[Guide] Throttling the selected guide: ${o.key}`);
366
+ return;
367
+ }
368
+ const h = this.stage.resolved === o.key ? o : void 0;
331
369
  return this.knock.log(
332
- `[Guide] Returning \`${o == null ? void 0 : o.key}\` (stage: ${y(this.stage)})`
333
- ), o;
370
+ `[Guide] Returning \`${h == null ? void 0 : h.key}\` (stage: ${v(this.stage)})`
371
+ ), h;
334
372
  }
335
373
  case "closed": {
336
- const o = this.stage.resolved === i.key ? i : void 0;
374
+ if (c) {
375
+ this.knock.log(`[Guide] Throttling the selected guide: ${o.key}`);
376
+ return;
377
+ }
378
+ const h = this.stage.resolved === o.key ? o : void 0;
337
379
  return this.knock.log(
338
- `[Guide] Returning \`${o == null ? void 0 : o.key}\` (stage: ${y(this.stage)})`
339
- ), o;
380
+ `[Guide] Returning \`${h == null ? void 0 : h.key}\` (stage: ${v(this.stage)})`
381
+ ), h;
340
382
  }
341
383
  }
342
384
  }
385
+ // Record select query results by accumulating them by 1) key or type first,
386
+ // and then 2) "one" or "all".
387
+ maybeRecordSelectResult(e) {
388
+ if (!e.metadata) return;
389
+ const { opts: t, filters: s, limit: i } = e.metadata;
390
+ if (!t.recordSelectQuery || !s.key && !s.type || !this.stage || this.stage.status === "closed") return;
391
+ const n = this.stage.results.key || {};
392
+ s.key && (n[s.key] = {
393
+ ...n[s.key] || {},
394
+ [i]: e
395
+ });
396
+ const r = this.stage.results.type || {};
397
+ s.type && (r[s.type] = {
398
+ ...r[s.type] || {},
399
+ [i]: e
400
+ }), this.stage = {
401
+ ...this.stage,
402
+ results: { key: n, type: r }
403
+ };
404
+ }
405
+ getStage() {
406
+ return this.stage;
407
+ }
343
408
  openGroupStage() {
344
409
  this.knock.log("[Guide] Opening a new group stage");
345
410
  const {
346
- orderResolutionDuration: e = $
411
+ orderResolutionDuration: e = K
347
412
  } = this.options, t = setTimeout(() => {
348
413
  this.closePendingGroupStage(), this.incrementCounter();
349
414
  }, e);
350
415
  return this.stage = {
351
416
  status: "open",
352
417
  ordered: [],
418
+ results: {},
353
419
  timeoutId: t
354
420
  }, this.stage;
355
421
  }
@@ -358,10 +424,8 @@ class B {
358
424
  closePendingGroupStage() {
359
425
  if (this.knock.log("[Guide] .closePendingGroupStage"), !this.stage || this.stage.status === "closed") return;
360
426
  this.ensureClearTimeout();
361
- let e;
362
- return this.store.state.debug.forcedGuideKey && (e = this.stage.ordered.find(
363
- (t) => t === this.store.state.debug.forcedGuideKey
364
- )), e || (e = this.stage.ordered.find((t) => t !== void 0)), this.knock.log(
427
+ const e = this.stage.ordered.find((t) => t !== void 0);
428
+ return this.knock.log(
365
429
  `[Guide] Closing the current group stage: resolved=${e}`
366
430
  ), this.stage = {
367
431
  ...this.stage,
@@ -418,30 +482,30 @@ class B {
418
482
  seen_at: (/* @__PURE__ */ new Date()).toISOString()
419
483
  });
420
484
  if (!s) return;
421
- const r = {
485
+ const i = {
422
486
  ...this.buildEngagementEventBaseParams(e, s),
423
487
  content: s.content,
424
488
  data: this.targetParams.data
425
489
  };
426
490
  return this.knock.user.markGuideStepAs(
427
491
  "seen",
428
- r
492
+ i
429
493
  ), s;
430
494
  }
431
495
  async markAsInteracted(e, t, s) {
432
496
  this.knock.log(
433
497
  `[Guide] Marking as interacted (Guide key: ${e.key}; Step ref:${t.ref})`
434
498
  );
435
- const r = (/* @__PURE__ */ new Date()).toISOString(), n = this.setStepMessageAttrs(e.key, t.ref, {
436
- read_at: r,
437
- interacted_at: r
499
+ const i = (/* @__PURE__ */ new Date()).toISOString(), n = this.setStepMessageAttrs(e.key, t.ref, {
500
+ read_at: i,
501
+ interacted_at: i
438
502
  });
439
503
  if (!n) return;
440
- const i = {
504
+ const r = {
441
505
  ...this.buildEngagementEventBaseParams(e, n),
442
506
  metadata: s
443
507
  };
444
- return this.knock.user.markGuideStepAs("interacted", i), n;
508
+ return this.knock.user.markGuideStepAs("interacted", r), n;
445
509
  }
446
510
  async markAsArchived(e, t) {
447
511
  if (t.message.archived_at) return;
@@ -452,11 +516,11 @@ class B {
452
516
  archived_at: (/* @__PURE__ */ new Date()).toISOString()
453
517
  });
454
518
  if (!s) return;
455
- const r = this.buildEngagementEventBaseParams(e, s);
519
+ const i = this.buildEngagementEventBaseParams(e, s);
456
520
  return this.knock.user.markGuideStepAs(
457
521
  "archived",
458
522
  {
459
- ...r,
523
+ ...i,
460
524
  unthrottled: e.bypass_global_group_limit
461
525
  }
462
526
  ), s;
@@ -469,29 +533,30 @@ class B {
469
533
  ...e,
470
534
  // Get the next unarchived step.
471
535
  getStep() {
472
- return t.store.state.debug.forcedGuideKey === this.key ? this.steps[0] : this.steps.find((r) => !r.message.archived_at);
536
+ var i;
537
+ return ((i = t.store.state.debug) == null ? void 0 : i.forcedGuideKey) === this.key ? this.steps[0] : this.steps.find((n) => !n.message.archived_at);
473
538
  }
474
539
  };
475
- return s.getStep = s.getStep.bind(s), s.steps = e.steps.map(({ message: r, ...n }) => {
476
- const i = {
540
+ return s.getStep = s.getStep.bind(s), s.steps = e.steps.map(({ message: i, ...n }) => {
541
+ const r = {
477
542
  ...n,
478
- message: { ...r },
543
+ message: { ...i },
479
544
  markAsSeen() {
480
545
  return t.markAsSeen(s, this);
481
546
  },
482
- markAsInteracted({ metadata: o } = {}) {
483
- return t.markAsInteracted(s, this, o);
547
+ markAsInteracted({ metadata: a } = {}) {
548
+ return t.markAsInteracted(s, this, a);
484
549
  },
485
550
  markAsArchived() {
486
551
  return t.markAsArchived(s, this);
487
552
  }
488
553
  };
489
- return i.markAsSeen = i.markAsSeen.bind(i), i.markAsInteracted = i.markAsInteracted.bind(i), i.markAsArchived = i.markAsArchived.bind(i), i;
490
- }), s.activation_url_patterns = e.activation_url_patterns.map((r) => ({
491
- ...r,
492
- pattern: new C({
493
- pathname: r.pathname ?? void 0,
494
- search: r.search ?? void 0
554
+ return r.markAsSeen = r.markAsSeen.bind(r), r.markAsInteracted = r.markAsInteracted.bind(r), r.markAsArchived = r.markAsArchived.bind(r), r;
555
+ }), s.activation_url_patterns = e.activation_url_patterns.map((i) => ({
556
+ ...i,
557
+ pattern: new w({
558
+ pathname: i.pathname ?? void 0,
559
+ search: i.search ?? void 0
495
560
  })
496
561
  })), s;
497
562
  }
@@ -499,34 +564,34 @@ class B {
499
564
  const t = {
500
565
  ...this.targetParams,
501
566
  ...e
502
- };
503
- this.store.state.debug.forcedGuideKey && (t.force_all_guides = !0);
504
- let r = Object.fromEntries(
567
+ }, s = this.store.state.debug;
568
+ (s != null && s.forcedGuideKey || s != null && s.debugging) && (t.force_all_guides = !0);
569
+ let i = Object.fromEntries(
505
570
  Object.entries(t).filter(
506
- ([n, i]) => i != null
571
+ ([n, r]) => r != null
507
572
  )
508
573
  );
509
- return r = r.data ? { ...r, data: JSON.stringify(r.data) } : r, r;
574
+ return i = i.data ? { ...i, data: JSON.stringify(i.data) } : i, i;
510
575
  }
511
576
  formatQueryKey(e) {
512
577
  const s = Object.keys(e).sort().map(
513
578
  (n) => `${encodeURIComponent(n)}=${encodeURIComponent(e[n])}`
514
- ).join("&"), r = U(this.knock.userId);
515
- return s ? `${r}?${s}` : r;
579
+ ).join("&"), i = F(this.knock.userId);
580
+ return s ? `${i}?${s}` : i;
516
581
  }
517
582
  setStepMessageAttrs(e, t, s) {
518
- let r;
583
+ let i;
519
584
  return s.archived_at && this.clearGroupStage(), this.store.setState((n) => {
520
- let i = n.guides[e];
521
- if (!i) return n;
522
- const o = i.steps.map((c) => (c.ref !== t || (c.message = { ...c.message, ...s }, r = c), c));
523
- i = r ? { ...i, steps: o } : i;
524
- const a = { ...n.guides, [i.key]: i }, h = s.archived_at && !i.bypass_global_group_limit ? {
585
+ let r = n.guides[e];
586
+ if (!r) return n;
587
+ const a = r.steps.map((d) => (d.ref !== t || (d.message = { ...d.message, ...s }, i = d), d));
588
+ r = i ? { ...r, steps: a } : r;
589
+ const o = { ...n.guides, [r.key]: r }, c = s.archived_at && !r.bypass_global_group_limit ? {
525
590
  ...n.guideGroupDisplayLogs,
526
- [R]: s.archived_at
591
+ [P]: s.archived_at
527
592
  } : n.guideGroupDisplayLogs;
528
- return { ...n, guides: a, guideGroupDisplayLogs: h };
529
- }), r;
593
+ return { ...n, guides: o, guideGroupDisplayLogs: c };
594
+ }), i;
530
595
  }
531
596
  buildEngagementEventBaseParams(e, t) {
532
597
  return {
@@ -542,38 +607,38 @@ class B {
542
607
  this.patchClosedGroupStage();
543
608
  const t = this.localCopy(e.guide);
544
609
  this.store.setState((s) => {
545
- const r = { ...s.guides, [t.key]: t };
546
- return { ...s, guides: r };
610
+ const i = { ...s.guides, [t.key]: t };
611
+ return { ...s, guides: i };
547
612
  });
548
613
  }
549
614
  removeGuide({ data: e }) {
550
615
  this.patchClosedGroupStage(), this.store.setState((t) => {
551
- const { [e.guide.key]: s, ...r } = t.guides;
552
- return { ...t, guides: r };
616
+ const { [e.guide.key]: s, ...i } = t.guides;
617
+ return { ...t, guides: i };
553
618
  });
554
619
  }
555
620
  addOrReplaceGuideGroup({
556
621
  data: e
557
622
  }) {
558
623
  this.patchClosedGroupStage(), this.store.setState((t) => {
559
- const s = [e.guide_group], r = e.guide_group.display_sequence_unthrottled || [], n = e.guide_group.display_sequence_throttled || [];
560
- let i = t.guides;
561
- return i = r.reduce((o, a) => {
562
- if (!o[a]) return o;
563
- const h = { ...o[a], bypass_global_group_limit: !0 };
564
- return { ...o, [a]: h };
565
- }, i), i = n.reduce((o, a) => {
566
- if (!o[a]) return o;
567
- const h = { ...o[a], bypass_global_group_limit: !1 };
568
- return { ...o, [a]: h };
569
- }, i), { ...t, guides: i, guideGroups: s };
624
+ const s = [e.guide_group], i = e.guide_group.display_sequence_unthrottled || [], n = e.guide_group.display_sequence_throttled || [];
625
+ let r = t.guides;
626
+ return r = i.reduce((a, o) => {
627
+ if (!a[o]) return a;
628
+ const c = { ...a[o], bypass_global_group_limit: !0 };
629
+ return { ...a, [o]: c };
630
+ }, r), r = n.reduce((a, o) => {
631
+ if (!a[o]) return a;
632
+ const c = { ...a[o], bypass_global_group_limit: !1 };
633
+ return { ...a, [o]: c };
634
+ }, r), { ...t, guides: r, guideGroups: s };
570
635
  });
571
636
  }
572
637
  updatePreviewGuide({ data: e }) {
573
638
  const t = this.localCopy(e.guide);
574
639
  this.store.setState((s) => {
575
- const r = { ...s.previewGuides, [t.key]: t };
576
- return { ...s, previewGuides: r };
640
+ const i = { ...s.previewGuides, [t.key]: t };
641
+ return { ...s, previewGuides: i };
577
642
  });
578
643
  }
579
644
  // Returns whether debug params have changed. For guide key, we only check
@@ -582,19 +647,19 @@ class B {
582
647
  return !!e.forcedGuideKey != !!t.forcedGuideKey || e.previewSessionId !== t.previewSessionId;
583
648
  }
584
649
  listenForLocationChangesFromWindow() {
585
- const e = l();
650
+ const e = k();
586
651
  if (e != null && e.history && (e != null && e.addEventListener)) {
587
652
  e.addEventListener("popstate", this.handleLocationChange), e.addEventListener("hashchange", this.handleLocationChange);
588
653
  const t = e.history.pushState, s = e.history.replaceState;
589
654
  e.history.pushState = new Proxy(t, {
590
- apply: (r, n, i) => {
591
- Reflect.apply(r, n, i), setTimeout(() => {
655
+ apply: (i, n, r) => {
656
+ Reflect.apply(i, n, r), setTimeout(() => {
592
657
  this.handleLocationChange();
593
658
  }, 0);
594
659
  }
595
660
  }), e.history.replaceState = new Proxy(s, {
596
- apply: (r, n, i) => {
597
- Reflect.apply(r, n, i), setTimeout(() => {
661
+ apply: (i, n, r) => {
662
+ Reflect.apply(i, n, r), setTimeout(() => {
598
663
  this.handleLocationChange();
599
664
  }, 0);
600
665
  }
@@ -605,13 +670,14 @@ class B {
605
670
  );
606
671
  }
607
672
  removeLocationChangeEventListeners() {
608
- const e = l();
673
+ const e = k();
609
674
  !(e != null && e.history) || !(e != null && e.removeEventListener) || (e.removeEventListener("popstate", this.handleLocationChange), e.removeEventListener("hashchange", this.handleLocationChange), this.pushStateFn && (e.history.pushState = this.pushStateFn, this.pushStateFn = void 0), this.replaceStateFn && (e.history.replaceState = this.replaceStateFn, this.replaceStateFn = void 0));
610
675
  }
611
676
  }
612
677
  export {
613
- g as DEBUG_QUERY_PARAMS,
614
- B as KnockGuideClient,
615
- U as guidesApiRootPath
678
+ p as DEBUG_QUERY_PARAMS,
679
+ W as KnockGuideClient,
680
+ j as checkActivatable,
681
+ F as guidesApiRootPath
616
682
  };
617
683
  //# sourceMappingURL=client.mjs.map