@knocklabs/client 0.16.5 → 0.17.0

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,85 +1,111 @@
1
- var y = Object.defineProperty;
2
- var S = (u, e, t) => e in u ? y(u, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[e] = t;
3
- var c = (u, e, t) => S(u, typeof e != "symbol" ? e + "" : e, t);
4
- import { Store as v } from "@tanstack/store";
5
- import { URLPattern as G } from "urlpattern-polyfill";
6
- import { byKey as _, mockDefaultGroup as C, formatFilters as g, findDefaultGroup as m, DEFAULT_GROUP_KEY as p, checkIfThrottled as b, SelectionResult as I } from "./helpers.mjs";
7
- const A = 50, E = 30 * 1e3, L = 3, l = () => {
1
+ var v = Object.defineProperty;
2
+ var G = (a, e, t) => e in a ? v(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
3
+ var d = (a, e, t) => G(a, typeof e != "symbol" ? e + "" : e, t);
4
+ import { Store as _ } from "@tanstack/store";
5
+ import { URLPattern as b } from "urlpattern-polyfill";
6
+ import { byKey as C, mockDefaultGroup as I, formatFilters as g, findDefaultGroup as y, DEFAULT_GROUP_KEY as p, checkIfThrottled as w, SelectionResult as E, newUrl as A, predicateUrlRules as R, predicateUrlPatterns as L } from "./helpers.mjs";
7
+ const P = 50, D = 30 * 1e3, T = 3, k = {
8
+ GUIDE_KEY: "knock_guide_key",
9
+ PREVIEW_SESSION_ID: "knock_preview_session_id"
10
+ }, l = () => {
8
11
  if (typeof window < "u")
9
12
  return window;
10
- }, R = (u) => `/v1/users/${u}/guides`, k = (u, e = {}) => {
11
- const t = new I(), s = m(u.guideGroups);
13
+ }, K = (a) => `/v1/users/${a}/guides`, f = () => {
14
+ const a = l();
15
+ if (!a)
16
+ return { forcedGuideKey: null, previewSessionId: null };
17
+ const e = new URLSearchParams(a.location.search), t = e.get(k.GUIDE_KEY), s = e.get(k.PREVIEW_SESSION_ID);
18
+ return { forcedGuideKey: t, previewSessionId: s };
19
+ }, m = (a, e = {}) => {
20
+ const t = new E(), s = y(a.guideGroups);
12
21
  if (!s) return t;
13
- const n = s.display_sequence, i = u.location;
14
- for (const [r, o] of n.entries()) {
15
- const a = u.guides[o];
16
- !a || !T(a, { location: i, filters: e }) || t.set(r, a);
22
+ const i = [...s.display_sequence], n = a.location;
23
+ if (a.debug.forcedGuideKey) {
24
+ const r = i.indexOf(a.debug.forcedGuideKey);
25
+ r > -1 && i.splice(r, 1), i.unshift(a.debug.forcedGuideKey);
26
+ }
27
+ for (const [r, o] of i.entries()) {
28
+ let u = a.guides[o];
29
+ !u || !O(u, {
30
+ location: n,
31
+ filters: e,
32
+ debug: a.debug
33
+ }) || (a.debug.forcedGuideKey === o && a.previewGuides[o] && (u = a.previewGuides[o]), t.set(r, u));
17
34
  }
18
35
  return t.metadata = { guideGroup: s }, t;
19
- }, T = (u, { location: e, filters: t = {} }) => {
20
- if (t.type && t.type !== u.type || t.key && t.key !== u.key || u.steps.every((n) => !!n.message.archived_at))
36
+ }, O = (a, { location: e, filters: t = {}, debug: s = {} }) => {
37
+ if (s.forcedGuideKey === a.key)
38
+ return !0;
39
+ if (t.type && t.type !== a.type || t.key && t.key !== a.key || a.steps.every((o) => !!o.message.archived_at))
21
40
  return !1;
22
- const s = u.activation_location_rules || [];
23
- return !(s.length > 0 && e && !s.reduce((i, r) => {
24
- if (i === !1) return !1;
25
- switch (r.directive) {
26
- case "allow":
27
- return i === !0 || r.pattern.test(e) ? !0 : void 0;
28
- case "block":
29
- return r.pattern.test(e) ? !1 : i;
30
- }
31
- }, void 0));
41
+ const i = e ? A(e) : void 0, n = a.activation_url_rules || [], r = a.activation_url_patterns || [];
42
+ if (i && n.length > 0) {
43
+ if (!R(i, n)) return !1;
44
+ } else if (i && r.length > 0 && !L(i, r))
45
+ return !1;
46
+ return !0;
32
47
  };
33
- class $ {
34
- constructor(e, t, s = {}, n = {}) {
35
- c(this, "store");
48
+ class j {
49
+ constructor(e, t, s = {}, i = {}) {
50
+ d(this, "store");
36
51
  // Phoenix channels for real time guide updates over websocket
37
- c(this, "socket");
38
- c(this, "socketChannel");
39
- c(this, "socketChannelTopic");
40
- c(this, "socketEventTypes", [
52
+ d(this, "socket");
53
+ d(this, "socketChannel");
54
+ d(this, "socketChannelTopic");
55
+ d(this, "socketEventTypes", [
41
56
  "guide.added",
42
57
  "guide.updated",
43
58
  "guide.removed",
44
59
  "guide_group.added",
45
- "guide_group.updated"
60
+ "guide_group.updated",
61
+ "guide.live_preview_updated"
46
62
  ]);
47
- c(this, "subscribeRetryCount", 0);
63
+ d(this, "subscribeRetryCount", 0);
48
64
  // Original history methods to monkey patch, or restore in cleanups.
49
- c(this, "pushStateFn");
50
- c(this, "replaceStateFn");
65
+ d(this, "pushStateFn");
66
+ d(this, "replaceStateFn");
51
67
  // Guides that are competing to render are "staged" first without rendering
52
68
  // and ranked based on its relative order in the group over a duration of time
53
69
  // to resolve and render the prevailing one.
54
- c(this, "stage");
55
- c(this, "counterIntervalId");
70
+ d(this, "stage");
71
+ d(this, "counterIntervalId");
56
72
  // Define as an arrow func property to always bind this to the class instance.
57
- c(this, "handleLocationChange", () => {
73
+ d(this, "handleLocationChange", () => {
58
74
  const e = l();
59
75
  if (!(e != null && e.location)) return;
60
76
  const t = e.location.href;
61
- this.store.state.location !== t && (this.knock.log(`[Guide] Handle Location change: ${t}`), this.setLocation(t));
77
+ if (this.store.state.location === t) return;
78
+ this.knock.log(`[Guide] Handle Location change: ${t}`);
79
+ const s = this.store.state.debug, i = f();
80
+ this.setLocation(t, { debug: i }), this.checkDebugStateChanged(
81
+ s,
82
+ i
83
+ ) && (this.knock.log(
84
+ "[Guide] Debug state changed, refetching guides and resubscribing to the websocket channel"
85
+ ), this.fetch(), this.subscribe());
62
86
  });
63
- this.knock = e, this.channelId = t, this.targetParams = s, this.options = n;
64
- const { trackLocationFromWindow: i = !0 } = n, r = l(), o = i ? r == null ? void 0 : r.location.href : void 0;
65
- this.store = new v({
87
+ this.knock = e, this.channelId = t, this.targetParams = s, this.options = i;
88
+ const { trackLocationFromWindow: n = !0 } = i, r = l(), o = n ? r == null ? void 0 : r.location.href : void 0, u = f();
89
+ this.store = new _({
66
90
  guideGroups: [],
67
91
  guideGroupDisplayLogs: {},
68
92
  guides: {},
93
+ previewGuides: {},
69
94
  queries: {},
70
95
  location: o,
71
96
  // Increment to update the state store and trigger re-selection.
72
- counter: 0
97
+ counter: 0,
98
+ debug: u
73
99
  });
74
- const { socket: a } = this.knock.client();
75
- this.socket = a, this.socketChannelTopic = `guides:${t}`, i && this.listenForLocationChangesFromWindow(), this.startCounterInterval(), this.knock.log("[Guide] Initialized a guide client");
100
+ const { socket: c } = this.knock.client();
101
+ this.socket = c, this.socketChannelTopic = `guides:${t}`, n && this.listenForLocationChangesFromWindow(), this.startCounterInterval(), this.knock.log("[Guide] Initialized a guide client");
76
102
  }
77
103
  incrementCounter() {
78
104
  this.knock.log("[Guide] Incrementing the counter"), this.store.setState((e) => ({ ...e, counter: e.counter + 1 }));
79
105
  }
80
106
  startCounterInterval() {
81
107
  const {
82
- throttleCheckInterval: e = E
108
+ throttleCheckInterval: e = D
83
109
  } = this.options;
84
110
  this.counterIntervalId = setInterval(() => {
85
111
  this.knock.log("[Guide] Counter interval tick"), !(this.stage && this.stage.status !== "closed") && this.incrementCounter();
@@ -93,51 +119,56 @@ class $ {
93
119
  }
94
120
  async fetch(e) {
95
121
  this.knock.failIfNotAuthenticated(), this.knock.log("[Guide] Loading all eligible guides");
96
- const t = this.buildQueryParams(e == null ? void 0 : e.filters), s = this.formatQueryKey(t), n = this.store.state.queries[s];
97
- if (n)
98
- return n;
122
+ const t = this.buildQueryParams(e == null ? void 0 : e.filters), s = this.formatQueryKey(t), i = this.store.state.queries[s];
123
+ if (i)
124
+ return i;
99
125
  this.store.setState((r) => ({
100
126
  ...r,
101
127
  queries: { ...r.queries, [s]: { status: "loading" } }
102
128
  }));
103
- let i;
129
+ let n;
104
130
  try {
105
131
  const r = await this.knock.user.getGuides(this.channelId, t);
106
- i = { status: "ok" };
107
- const { entries: o, guide_groups: a, guide_group_display_logs: h } = r;
108
- this.store.setState((d) => ({
109
- ...d,
110
- guideGroups: (a == null ? void 0 : a.length) > 0 ? a : [C(o)],
111
- guideGroupDisplayLogs: h || {},
112
- guides: _(o.map((f) => this.localCopy(f))),
113
- queries: { ...d.queries, [s]: i }
132
+ n = { status: "ok" };
133
+ const { entries: o, guide_groups: u, guide_group_display_logs: c } = r;
134
+ this.store.setState((h) => ({
135
+ ...h,
136
+ guideGroups: (u == null ? void 0 : u.length) > 0 ? u : [I(o)],
137
+ guideGroupDisplayLogs: c || {},
138
+ guides: C(o.map((S) => this.localCopy(S))),
139
+ queries: { ...h.queries, [s]: n }
114
140
  }));
115
141
  } catch (r) {
116
- i = { status: "error", error: r }, this.store.setState((o) => ({
142
+ n = { status: "error", error: r }, this.store.setState((o) => ({
117
143
  ...o,
118
- queries: { ...o.queries, [s]: i }
144
+ queries: { ...o.queries, [s]: n }
119
145
  }));
120
146
  }
121
- return i;
147
+ return n;
122
148
  }
123
149
  subscribe() {
124
150
  if (!this.socket) return;
125
151
  this.knock.failIfNotAuthenticated(), this.knock.log("[Guide] Subscribing to real time updates"), this.socket.isConnected() || this.socket.connect(), this.socketChannel && this.unsubscribe();
126
- const e = { ...this.targetParams, user_id: this.knock.userId }, t = this.socket.channel(this.socketChannelTopic, e);
127
- for (const s of this.socketEventTypes)
128
- t.on(s, (n) => this.handleSocketEvent(n));
129
- ["closed", "errored"].includes(t.state) && (this.subscribeRetryCount = 0, t.join().receive("ok", () => {
152
+ const e = this.store.state.debug, t = {
153
+ ...this.targetParams,
154
+ user_id: this.knock.userId,
155
+ force_all_guides: e.forcedGuideKey ? !0 : void 0,
156
+ preview_session_id: e.previewSessionId || void 0
157
+ }, s = this.socket.channel(this.socketChannelTopic, t);
158
+ for (const i of this.socketEventTypes)
159
+ s.on(i, (n) => this.handleSocketEvent(n));
160
+ ["closed", "errored"].includes(s.state) && (this.subscribeRetryCount = 0, s.join().receive("ok", () => {
130
161
  this.knock.log("[Guide] Successfully joined channel");
131
- }).receive("error", (s) => {
162
+ }).receive("error", (i) => {
132
163
  this.knock.log(
133
- `[Guide] Failed to join channel: ${JSON.stringify(s)}`
164
+ `[Guide] Failed to join channel: ${JSON.stringify(i)}`
134
165
  ), this.handleChannelJoinError();
135
166
  }).receive("timeout", () => {
136
167
  this.knock.log("[Guide] Channel join timed out"), this.handleChannelJoinError();
137
- })), this.socketChannel = t;
168
+ })), this.socketChannel = s;
138
169
  }
139
170
  handleChannelJoinError() {
140
- if (this.subscribeRetryCount >= L) {
171
+ if (this.subscribeRetryCount >= T) {
141
172
  this.knock.log(
142
173
  `[Guide] Channel join max retry limit reached: ${this.subscribeRetryCount}`
143
174
  ), this.unsubscribe();
@@ -165,12 +196,23 @@ class $ {
165
196
  case "guide_group.added":
166
197
  case "guide_group.updated":
167
198
  return this.addOrReplaceGuideGroup(e);
199
+ case "guide.live_preview_updated":
200
+ return this.updatePreviewGuide(e);
168
201
  default:
169
202
  return;
170
203
  }
171
204
  }
172
- setLocation(e) {
173
- this.clearGroupStage(), this.store.setState((t) => ({ ...t, location: e }));
205
+ setLocation(e, t = {}) {
206
+ this.clearGroupStage(), this.store.setState((s) => {
207
+ var n;
208
+ const i = (n = t == null ? void 0 : t.debug) != null && n.previewSessionId ? s.previewGuides : {};
209
+ return {
210
+ ...s,
211
+ ...t,
212
+ previewGuides: i,
213
+ location: e
214
+ };
215
+ });
174
216
  }
175
217
  //
176
218
  // Store selector
@@ -179,41 +221,41 @@ class $ {
179
221
  if (Object.keys(e.guides).length === 0)
180
222
  return [];
181
223
  this.knock.log(`[Guide] Selecting guides for: ${g(t)}`);
182
- const s = k(e, t);
224
+ const s = m(e, t);
183
225
  return s.size === 0 ? (this.knock.log("[Guide] Selection returned zero result"), []) : [...s.values()];
184
226
  }
185
227
  selectGuide(e, t = {}) {
186
228
  if (Object.keys(e.guides).length === 0)
187
229
  return;
188
230
  this.knock.log(`[Guide] Selecting a guide for: ${g(t)}`);
189
- const s = k(e, t);
231
+ const s = m(e, t);
190
232
  if (s.size === 0) {
191
233
  this.knock.log("[Guide] Selection returned zero result");
192
234
  return;
193
235
  }
194
- const [n, i] = [...s][0];
195
- if (i.bypass_global_group_limit)
196
- return i;
197
- const r = m(e.guideGroups), o = e.guideGroupDisplayLogs[p];
198
- if (!(r && r.display_interval && o && b(
236
+ const [i, n] = [...s][0];
237
+ if (n.bypass_global_group_limit)
238
+ return n;
239
+ const r = y(e.guideGroups), o = e.guideGroupDisplayLogs[p];
240
+ if (!(r && r.display_interval && o && w(
199
241
  o,
200
242
  r.display_interval
201
243
  )))
202
244
  switch (this.stage || (this.stage = this.openGroupStage()), this.stage.status) {
203
245
  case "open": {
204
- this.knock.log(`[Guide] Addng to the group stage: ${i.key}`), this.stage.ordered[n] = i.key;
246
+ this.knock.log(`[Guide] Addng to the group stage: ${n.key}`), this.stage.ordered[i] = n.key;
205
247
  return;
206
248
  }
207
249
  case "patch":
208
- return this.knock.log(`[Guide] Patching the group stage: ${i.key}`), this.stage.ordered[n] = i.key, this.stage.resolved === i.key ? i : void 0;
250
+ return this.knock.log(`[Guide] Patching the group stage: ${n.key}`), this.stage.ordered[i] = n.key, this.stage.resolved === n.key ? n : void 0;
209
251
  case "closed":
210
- return this.stage.resolved === i.key ? i : void 0;
252
+ return this.stage.resolved === n.key ? n : void 0;
211
253
  }
212
254
  }
213
255
  openGroupStage() {
214
256
  this.knock.log("[Guide] Opening a new group stage");
215
257
  const {
216
- orderResolutionDuration: e = A
258
+ orderResolutionDuration: e = P
217
259
  } = this.options, t = setTimeout(() => {
218
260
  this.closePendingGroupStage(), this.incrementCounter();
219
261
  }, e);
@@ -226,13 +268,17 @@ class $ {
226
268
  // Close the current non-closed stage to resolve the prevailing guide up next
227
269
  // for display amongst the ones that have been staged.
228
270
  closePendingGroupStage() {
229
- if (!(!this.stage || this.stage.status === "closed"))
230
- return this.knock.log("[Guide] Closing the current group stage"), this.ensureClearTimeout(), this.stage = {
231
- ...this.stage,
232
- status: "closed",
233
- resolved: this.stage.ordered.find((e) => e !== void 0),
234
- timeoutId: null
235
- }, this.stage;
271
+ if (!this.stage || this.stage.status === "closed") return;
272
+ this.knock.log("[Guide] Closing the current group stage"), this.ensureClearTimeout();
273
+ let e;
274
+ return this.store.state.debug.forcedGuideKey && (e = this.stage.ordered.find(
275
+ (t) => t === this.store.state.debug.forcedGuideKey
276
+ )), e || (e = this.stage.ordered.find((t) => t !== void 0)), this.stage = {
277
+ ...this.stage,
278
+ status: "closed",
279
+ resolved: e,
280
+ timeoutId: null
281
+ }, this.stage;
236
282
  }
237
283
  // Set the current closed stage status to "patch" to allow re-running
238
284
  // selections and re-building a group stage with the latest/updated state,
@@ -280,7 +326,7 @@ class $ {
280
326
  seen_at: (/* @__PURE__ */ new Date()).toISOString()
281
327
  });
282
328
  if (!s) return;
283
- const n = {
329
+ const i = {
284
330
  ...this.buildEngagementEventBaseParams(e, s),
285
331
  content: s.content,
286
332
  data: this.targetParams.data,
@@ -288,23 +334,23 @@ class $ {
288
334
  };
289
335
  return this.knock.user.markGuideStepAs(
290
336
  "seen",
291
- n
337
+ i
292
338
  ), s;
293
339
  }
294
340
  async markAsInteracted(e, t, s) {
295
341
  this.knock.log(
296
342
  `[Guide] Marking as interacted (Guide key: ${e.key}, Step ref:${t.ref})`
297
343
  );
298
- const n = (/* @__PURE__ */ new Date()).toISOString(), i = this.setStepMessageAttrs(e.key, t.ref, {
299
- read_at: n,
300
- interacted_at: n
344
+ const i = (/* @__PURE__ */ new Date()).toISOString(), n = this.setStepMessageAttrs(e.key, t.ref, {
345
+ read_at: i,
346
+ interacted_at: i
301
347
  });
302
- if (!i) return;
348
+ if (!n) return;
303
349
  const r = {
304
- ...this.buildEngagementEventBaseParams(e, i),
350
+ ...this.buildEngagementEventBaseParams(e, n),
305
351
  metadata: s
306
352
  };
307
- return this.knock.user.markGuideStepAs("interacted", r), i;
353
+ return this.knock.user.markGuideStepAs("interacted", r), n;
308
354
  }
309
355
  async markAsArchived(e, t) {
310
356
  if (t.message.archived_at) return;
@@ -315,11 +361,11 @@ class $ {
315
361
  archived_at: (/* @__PURE__ */ new Date()).toISOString()
316
362
  });
317
363
  if (!s) return;
318
- const n = this.buildEngagementEventBaseParams(e, s);
364
+ const i = this.buildEngagementEventBaseParams(e, s);
319
365
  return this.knock.user.markGuideStepAs(
320
366
  "archived",
321
367
  {
322
- ...n,
368
+ ...i,
323
369
  unthrottled: e.bypass_global_group_limit
324
370
  }
325
371
  ), s;
@@ -332,13 +378,13 @@ class $ {
332
378
  ...e,
333
379
  // Get the next unarchived step.
334
380
  getStep() {
335
- return this.steps.find((n) => !n.message.archived_at);
381
+ return t.store.state.debug.forcedGuideKey === this.key ? this.steps[0] : this.steps.find((i) => !i.message.archived_at);
336
382
  }
337
383
  };
338
- return s.getStep = s.getStep.bind(s), s.steps = e.steps.map(({ message: n, ...i }) => {
384
+ return s.getStep = s.getStep.bind(s), s.steps = e.steps.map(({ message: i, ...n }) => {
339
385
  const r = {
340
- ...i,
341
- message: { ...n },
386
+ ...n,
387
+ message: { ...i },
342
388
  markAsSeen() {
343
389
  if (!this.message.seen_at)
344
390
  return t.markAsSeen(s, this);
@@ -352,39 +398,43 @@ class $ {
352
398
  }
353
399
  };
354
400
  return r.markAsSeen = r.markAsSeen.bind(r), r.markAsInteracted = r.markAsInteracted.bind(r), r.markAsArchived = r.markAsArchived.bind(r), r;
355
- }), s.activation_location_rules = e.activation_location_rules.map((n) => ({
356
- ...n,
357
- pattern: new G({ pathname: n.pathname })
401
+ }), s.activation_url_patterns = e.activation_url_patterns.map((i) => ({
402
+ ...i,
403
+ pattern: new b({ pathname: i.pathname })
358
404
  })), s;
359
405
  }
360
406
  buildQueryParams(e = {}) {
361
- const t = { ...this.targetParams, ...e };
362
- let s = Object.fromEntries(
407
+ const t = {
408
+ ...this.targetParams,
409
+ ...e
410
+ };
411
+ this.store.state.debug.forcedGuideKey && (t.force_all_guides = !0);
412
+ let i = Object.fromEntries(
363
413
  Object.entries(t).filter(
364
- ([n, i]) => i != null
414
+ ([n, r]) => r != null
365
415
  )
366
416
  );
367
- return s = s.data ? { ...s, data: JSON.stringify(s.data) } : s, s;
417
+ return i = i.data ? { ...i, data: JSON.stringify(i.data) } : i, i;
368
418
  }
369
419
  formatQueryKey(e) {
370
420
  const s = Object.keys(e).sort().map(
371
- (i) => `${encodeURIComponent(i)}=${encodeURIComponent(e[i])}`
372
- ).join("&"), n = R(this.knock.userId);
373
- return s ? `${n}?${s}` : n;
421
+ (n) => `${encodeURIComponent(n)}=${encodeURIComponent(e[n])}`
422
+ ).join("&"), i = K(this.knock.userId);
423
+ return s ? `${i}?${s}` : i;
374
424
  }
375
425
  setStepMessageAttrs(e, t, s) {
376
- let n;
377
- return s.archived_at && this.clearGroupStage(), this.store.setState((i) => {
378
- const r = i.guides[e];
379
- if (!r) return i;
380
- const o = r.steps.map((d) => (d.ref !== t || (d.message = { ...d.message, ...s }, n = d), d));
426
+ let i;
427
+ return s.archived_at && this.clearGroupStage(), this.store.setState((n) => {
428
+ const r = n.guides[e];
429
+ if (!r) return n;
430
+ const o = r.steps.map((h) => (h.ref !== t || (h.message = { ...h.message, ...s }, i = h), h));
381
431
  r.steps = o;
382
- const a = { ...i.guides, [r.key]: r }, h = s.archived_at && !r.bypass_global_group_limit ? {
383
- ...i.guideGroupDisplayLogs,
432
+ const u = { ...n.guides, [r.key]: r }, c = s.archived_at && !r.bypass_global_group_limit ? {
433
+ ...n.guideGroupDisplayLogs,
384
434
  [p]: s.archived_at
385
- } : i.guideGroupDisplayLogs;
386
- return { ...i, guides: a, guideGroupDisplayLogs: h };
387
- }), n;
435
+ } : n.guideGroupDisplayLogs;
436
+ return { ...n, guides: u, guideGroupDisplayLogs: c };
437
+ }), i;
388
438
  }
389
439
  buildEngagementEventBaseParams(e, t) {
390
440
  return {
@@ -399,47 +449,59 @@ class $ {
399
449
  this.patchClosedGroupStage();
400
450
  const t = this.localCopy(e.guide);
401
451
  this.store.setState((s) => {
402
- const n = { ...s.guides, [t.key]: t };
403
- return { ...s, guides: n };
452
+ const i = { ...s.guides, [t.key]: t };
453
+ return { ...s, guides: i };
404
454
  });
405
455
  }
406
456
  removeGuide({ data: e }) {
407
457
  this.patchClosedGroupStage(), this.store.setState((t) => {
408
- const { [e.guide.key]: s, ...n } = t.guides;
409
- return { ...t, guides: n };
458
+ const { [e.guide.key]: s, ...i } = t.guides;
459
+ return { ...t, guides: i };
410
460
  });
411
461
  }
412
462
  addOrReplaceGuideGroup({
413
463
  data: e
414
464
  }) {
415
465
  this.patchClosedGroupStage(), this.store.setState((t) => {
416
- const s = [e.guide_group], n = e.guide_group.display_sequence_unthrottled || [], i = e.guide_group.display_sequence_throttled || [];
466
+ const s = [e.guide_group], i = e.guide_group.display_sequence_unthrottled || [], n = e.guide_group.display_sequence_throttled || [];
417
467
  let r = t.guides;
418
- return r = n.reduce((o, a) => {
419
- if (!o[a]) return o;
420
- const h = { ...o[a], bypass_global_group_limit: !0 };
421
- return { ...o, [a]: h };
422
- }, r), r = i.reduce((o, a) => {
423
- if (!o[a]) return o;
424
- const h = { ...o[a], bypass_global_group_limit: !1 };
425
- return { ...o, [a]: h };
468
+ return r = i.reduce((o, u) => {
469
+ if (!o[u]) return o;
470
+ const c = { ...o[u], bypass_global_group_limit: !0 };
471
+ return { ...o, [u]: c };
472
+ }, r), r = n.reduce((o, u) => {
473
+ if (!o[u]) return o;
474
+ const c = { ...o[u], bypass_global_group_limit: !1 };
475
+ return { ...o, [u]: c };
426
476
  }, r), { ...t, guides: r, guideGroups: s };
427
477
  });
428
478
  }
479
+ updatePreviewGuide({ data: e }) {
480
+ const t = this.localCopy(e.guide);
481
+ this.store.setState((s) => {
482
+ const i = { ...s.previewGuides, [t.key]: t };
483
+ return { ...s, previewGuides: i };
484
+ });
485
+ }
486
+ // Returns whether debug params have changed. For guide key, we only check
487
+ // presence since the exact value has no impact on fetch/subscribe
488
+ checkDebugStateChanged(e, t) {
489
+ return !!e.forcedGuideKey != !!t.forcedGuideKey || e.previewSessionId !== t.previewSessionId;
490
+ }
429
491
  listenForLocationChangesFromWindow() {
430
492
  const e = l();
431
493
  if (e != null && e.history) {
432
494
  e.addEventListener("popstate", this.handleLocationChange), e.addEventListener("hashchange", this.handleLocationChange);
433
495
  const t = e.history.pushState, s = e.history.replaceState;
434
496
  e.history.pushState = new Proxy(t, {
435
- apply: (n, i, r) => {
436
- Reflect.apply(n, i, r), setTimeout(() => {
497
+ apply: (i, n, r) => {
498
+ Reflect.apply(i, n, r), setTimeout(() => {
437
499
  this.handleLocationChange();
438
500
  }, 0);
439
501
  }
440
502
  }), e.history.replaceState = new Proxy(s, {
441
- apply: (n, i, r) => {
442
- Reflect.apply(n, i, r), setTimeout(() => {
503
+ apply: (i, n, r) => {
504
+ Reflect.apply(i, n, r), setTimeout(() => {
443
505
  this.handleLocationChange();
444
506
  }, 0);
445
507
  }
@@ -455,7 +517,8 @@ class $ {
455
517
  }
456
518
  }
457
519
  export {
458
- $ as KnockGuideClient,
459
- R as guidesApiRootPath
520
+ k as DEBUG_QUERY_PARAMS,
521
+ j as KnockGuideClient,
522
+ K as guidesApiRootPath
460
523
  };
461
524
  //# sourceMappingURL=client.mjs.map