@knocklabs/client 0.16.4 → 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.
- package/CHANGELOG.md +17 -0
- package/dist/cjs/api.js +1 -1
- package/dist/cjs/clients/guide/client.js +1 -1
- package/dist/cjs/clients/guide/client.js.map +1 -1
- package/dist/cjs/clients/guide/helpers.js +1 -1
- package/dist/cjs/clients/guide/helpers.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/api.mjs +1 -1
- package/dist/esm/clients/guide/client.mjs +219 -138
- package/dist/esm/clients/guide/client.mjs.map +1 -1
- package/dist/esm/clients/guide/helpers.mjs +47 -21
- package/dist/esm/clients/guide/helpers.mjs.map +1 -1
- package/dist/esm/index.mjs +10 -9
- package/dist/types/clients/guide/client.d.ts +15 -7
- package/dist/types/clients/guide/client.d.ts.map +1 -1
- package/dist/types/clients/guide/helpers.d.ts +5 -1
- package/dist/types/clients/guide/helpers.d.ts.map +1 -1
- package/dist/types/clients/guide/index.d.ts +1 -1
- package/dist/types/clients/guide/index.d.ts.map +1 -1
- package/dist/types/clients/guide/types.d.ts +33 -14
- package/dist/types/clients/guide/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/clients/guide/client.ts +207 -43
- package/src/clients/guide/helpers.ts +99 -0
- package/src/clients/guide/index.ts +1 -1
- package/src/clients/guide/types.ts +42 -16
|
@@ -1,84 +1,111 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { Store as
|
|
5
|
-
import { URLPattern as
|
|
6
|
-
import { byKey as
|
|
7
|
-
const
|
|
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
|
-
},
|
|
11
|
-
const
|
|
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
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
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
|
-
},
|
|
20
|
-
if (
|
|
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
|
|
23
|
-
|
|
24
|
-
if (i
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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 = {},
|
|
35
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
]);
|
|
63
|
+
d(this, "subscribeRetryCount", 0);
|
|
47
64
|
// Original history methods to monkey patch, or restore in cleanups.
|
|
48
|
-
|
|
49
|
-
|
|
65
|
+
d(this, "pushStateFn");
|
|
66
|
+
d(this, "replaceStateFn");
|
|
50
67
|
// Guides that are competing to render are "staged" first without rendering
|
|
51
68
|
// and ranked based on its relative order in the group over a duration of time
|
|
52
69
|
// to resolve and render the prevailing one.
|
|
53
|
-
|
|
54
|
-
|
|
70
|
+
d(this, "stage");
|
|
71
|
+
d(this, "counterIntervalId");
|
|
55
72
|
// Define as an arrow func property to always bind this to the class instance.
|
|
56
|
-
|
|
73
|
+
d(this, "handleLocationChange", () => {
|
|
57
74
|
const e = l();
|
|
58
75
|
if (!(e != null && e.location)) return;
|
|
59
76
|
const t = e.location.href;
|
|
60
|
-
this.store.state.location
|
|
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());
|
|
61
86
|
});
|
|
62
|
-
this.knock = e, this.channelId = t, this.targetParams = s, this.options =
|
|
63
|
-
const { trackLocationFromWindow:
|
|
64
|
-
this.store = new
|
|
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 _({
|
|
65
90
|
guideGroups: [],
|
|
66
91
|
guideGroupDisplayLogs: {},
|
|
67
92
|
guides: {},
|
|
93
|
+
previewGuides: {},
|
|
68
94
|
queries: {},
|
|
69
95
|
location: o,
|
|
70
96
|
// Increment to update the state store and trigger re-selection.
|
|
71
|
-
counter: 0
|
|
97
|
+
counter: 0,
|
|
98
|
+
debug: u
|
|
72
99
|
});
|
|
73
|
-
const { socket:
|
|
74
|
-
this.socket =
|
|
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");
|
|
75
102
|
}
|
|
76
103
|
incrementCounter() {
|
|
77
104
|
this.knock.log("[Guide] Incrementing the counter"), this.store.setState((e) => ({ ...e, counter: e.counter + 1 }));
|
|
78
105
|
}
|
|
79
106
|
startCounterInterval() {
|
|
80
107
|
const {
|
|
81
|
-
throttleCheckInterval: e =
|
|
108
|
+
throttleCheckInterval: e = D
|
|
82
109
|
} = this.options;
|
|
83
110
|
this.counterIntervalId = setInterval(() => {
|
|
84
111
|
this.knock.log("[Guide] Counter interval tick"), !(this.stage && this.stage.status !== "closed") && this.incrementCounter();
|
|
@@ -92,40 +119,62 @@ class O {
|
|
|
92
119
|
}
|
|
93
120
|
async fetch(e) {
|
|
94
121
|
this.knock.failIfNotAuthenticated(), this.knock.log("[Guide] Loading all eligible guides");
|
|
95
|
-
const t = this.buildQueryParams(e == null ? void 0 : e.filters), s = this.formatQueryKey(t),
|
|
96
|
-
if (
|
|
97
|
-
return
|
|
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;
|
|
98
125
|
this.store.setState((r) => ({
|
|
99
126
|
...r,
|
|
100
127
|
queries: { ...r.queries, [s]: { status: "loading" } }
|
|
101
128
|
}));
|
|
102
|
-
let
|
|
129
|
+
let n;
|
|
103
130
|
try {
|
|
104
131
|
const r = await this.knock.user.getGuides(this.channelId, t);
|
|
105
|
-
|
|
106
|
-
const { entries: o, guide_groups:
|
|
107
|
-
this.store.setState((
|
|
108
|
-
...
|
|
109
|
-
guideGroups: (
|
|
110
|
-
guideGroupDisplayLogs:
|
|
111
|
-
guides:
|
|
112
|
-
queries: { ...
|
|
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 }
|
|
113
140
|
}));
|
|
114
141
|
} catch (r) {
|
|
115
|
-
|
|
142
|
+
n = { status: "error", error: r }, this.store.setState((o) => ({
|
|
116
143
|
...o,
|
|
117
|
-
queries: { ...o.queries, [s]:
|
|
144
|
+
queries: { ...o.queries, [s]: n }
|
|
118
145
|
}));
|
|
119
146
|
}
|
|
120
|
-
return
|
|
147
|
+
return n;
|
|
121
148
|
}
|
|
122
149
|
subscribe() {
|
|
123
150
|
if (!this.socket) return;
|
|
124
151
|
this.knock.failIfNotAuthenticated(), this.knock.log("[Guide] Subscribing to real time updates"), this.socket.isConnected() || this.socket.connect(), this.socketChannel && this.unsubscribe();
|
|
125
|
-
const e =
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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", () => {
|
|
161
|
+
this.knock.log("[Guide] Successfully joined channel");
|
|
162
|
+
}).receive("error", (i) => {
|
|
163
|
+
this.knock.log(
|
|
164
|
+
`[Guide] Failed to join channel: ${JSON.stringify(i)}`
|
|
165
|
+
), this.handleChannelJoinError();
|
|
166
|
+
}).receive("timeout", () => {
|
|
167
|
+
this.knock.log("[Guide] Channel join timed out"), this.handleChannelJoinError();
|
|
168
|
+
})), this.socketChannel = s;
|
|
169
|
+
}
|
|
170
|
+
handleChannelJoinError() {
|
|
171
|
+
if (this.subscribeRetryCount >= T) {
|
|
172
|
+
this.knock.log(
|
|
173
|
+
`[Guide] Channel join max retry limit reached: ${this.subscribeRetryCount}`
|
|
174
|
+
), this.unsubscribe();
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
this.subscribeRetryCount++;
|
|
129
178
|
}
|
|
130
179
|
unsubscribe() {
|
|
131
180
|
if (this.socketChannel) {
|
|
@@ -147,12 +196,23 @@ class O {
|
|
|
147
196
|
case "guide_group.added":
|
|
148
197
|
case "guide_group.updated":
|
|
149
198
|
return this.addOrReplaceGuideGroup(e);
|
|
199
|
+
case "guide.live_preview_updated":
|
|
200
|
+
return this.updatePreviewGuide(e);
|
|
150
201
|
default:
|
|
151
202
|
return;
|
|
152
203
|
}
|
|
153
204
|
}
|
|
154
|
-
setLocation(e) {
|
|
155
|
-
this.clearGroupStage(), this.store.setState((
|
|
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
|
+
});
|
|
156
216
|
}
|
|
157
217
|
//
|
|
158
218
|
// Store selector
|
|
@@ -161,41 +221,41 @@ class O {
|
|
|
161
221
|
if (Object.keys(e.guides).length === 0)
|
|
162
222
|
return [];
|
|
163
223
|
this.knock.log(`[Guide] Selecting guides for: ${g(t)}`);
|
|
164
|
-
const s =
|
|
224
|
+
const s = m(e, t);
|
|
165
225
|
return s.size === 0 ? (this.knock.log("[Guide] Selection returned zero result"), []) : [...s.values()];
|
|
166
226
|
}
|
|
167
227
|
selectGuide(e, t = {}) {
|
|
168
228
|
if (Object.keys(e.guides).length === 0)
|
|
169
229
|
return;
|
|
170
230
|
this.knock.log(`[Guide] Selecting a guide for: ${g(t)}`);
|
|
171
|
-
const s =
|
|
231
|
+
const s = m(e, t);
|
|
172
232
|
if (s.size === 0) {
|
|
173
233
|
this.knock.log("[Guide] Selection returned zero result");
|
|
174
234
|
return;
|
|
175
235
|
}
|
|
176
|
-
const [
|
|
177
|
-
if (
|
|
178
|
-
return
|
|
179
|
-
const r =
|
|
180
|
-
if (!(r && r.display_interval && o &&
|
|
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(
|
|
181
241
|
o,
|
|
182
242
|
r.display_interval
|
|
183
243
|
)))
|
|
184
244
|
switch (this.stage || (this.stage = this.openGroupStage()), this.stage.status) {
|
|
185
245
|
case "open": {
|
|
186
|
-
this.knock.log(`[Guide] Addng to the group stage: ${
|
|
246
|
+
this.knock.log(`[Guide] Addng to the group stage: ${n.key}`), this.stage.ordered[i] = n.key;
|
|
187
247
|
return;
|
|
188
248
|
}
|
|
189
249
|
case "patch":
|
|
190
|
-
return this.knock.log(`[Guide] Patching the group stage: ${
|
|
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;
|
|
191
251
|
case "closed":
|
|
192
|
-
return this.stage.resolved ===
|
|
252
|
+
return this.stage.resolved === n.key ? n : void 0;
|
|
193
253
|
}
|
|
194
254
|
}
|
|
195
255
|
openGroupStage() {
|
|
196
256
|
this.knock.log("[Guide] Opening a new group stage");
|
|
197
257
|
const {
|
|
198
|
-
orderResolutionDuration: e =
|
|
258
|
+
orderResolutionDuration: e = P
|
|
199
259
|
} = this.options, t = setTimeout(() => {
|
|
200
260
|
this.closePendingGroupStage(), this.incrementCounter();
|
|
201
261
|
}, e);
|
|
@@ -208,13 +268,17 @@ class O {
|
|
|
208
268
|
// Close the current non-closed stage to resolve the prevailing guide up next
|
|
209
269
|
// for display amongst the ones that have been staged.
|
|
210
270
|
closePendingGroupStage() {
|
|
211
|
-
if (!
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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;
|
|
218
282
|
}
|
|
219
283
|
// Set the current closed stage status to "patch" to allow re-running
|
|
220
284
|
// selections and re-building a group stage with the latest/updated state,
|
|
@@ -262,7 +326,7 @@ class O {
|
|
|
262
326
|
seen_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
263
327
|
});
|
|
264
328
|
if (!s) return;
|
|
265
|
-
const
|
|
329
|
+
const i = {
|
|
266
330
|
...this.buildEngagementEventBaseParams(e, s),
|
|
267
331
|
content: s.content,
|
|
268
332
|
data: this.targetParams.data,
|
|
@@ -270,23 +334,23 @@ class O {
|
|
|
270
334
|
};
|
|
271
335
|
return this.knock.user.markGuideStepAs(
|
|
272
336
|
"seen",
|
|
273
|
-
|
|
337
|
+
i
|
|
274
338
|
), s;
|
|
275
339
|
}
|
|
276
340
|
async markAsInteracted(e, t, s) {
|
|
277
341
|
this.knock.log(
|
|
278
342
|
`[Guide] Marking as interacted (Guide key: ${e.key}, Step ref:${t.ref})`
|
|
279
343
|
);
|
|
280
|
-
const
|
|
281
|
-
read_at:
|
|
282
|
-
interacted_at:
|
|
344
|
+
const i = (/* @__PURE__ */ new Date()).toISOString(), n = this.setStepMessageAttrs(e.key, t.ref, {
|
|
345
|
+
read_at: i,
|
|
346
|
+
interacted_at: i
|
|
283
347
|
});
|
|
284
|
-
if (!
|
|
348
|
+
if (!n) return;
|
|
285
349
|
const r = {
|
|
286
|
-
...this.buildEngagementEventBaseParams(e,
|
|
350
|
+
...this.buildEngagementEventBaseParams(e, n),
|
|
287
351
|
metadata: s
|
|
288
352
|
};
|
|
289
|
-
return this.knock.user.markGuideStepAs("interacted", r),
|
|
353
|
+
return this.knock.user.markGuideStepAs("interacted", r), n;
|
|
290
354
|
}
|
|
291
355
|
async markAsArchived(e, t) {
|
|
292
356
|
if (t.message.archived_at) return;
|
|
@@ -297,11 +361,11 @@ class O {
|
|
|
297
361
|
archived_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
298
362
|
});
|
|
299
363
|
if (!s) return;
|
|
300
|
-
const
|
|
364
|
+
const i = this.buildEngagementEventBaseParams(e, s);
|
|
301
365
|
return this.knock.user.markGuideStepAs(
|
|
302
366
|
"archived",
|
|
303
367
|
{
|
|
304
|
-
...
|
|
368
|
+
...i,
|
|
305
369
|
unthrottled: e.bypass_global_group_limit
|
|
306
370
|
}
|
|
307
371
|
), s;
|
|
@@ -314,13 +378,13 @@ class O {
|
|
|
314
378
|
...e,
|
|
315
379
|
// Get the next unarchived step.
|
|
316
380
|
getStep() {
|
|
317
|
-
return this.steps.find((
|
|
381
|
+
return t.store.state.debug.forcedGuideKey === this.key ? this.steps[0] : this.steps.find((i) => !i.message.archived_at);
|
|
318
382
|
}
|
|
319
383
|
};
|
|
320
|
-
return s.getStep = s.getStep.bind(s), s.steps = e.steps.map(({ message:
|
|
384
|
+
return s.getStep = s.getStep.bind(s), s.steps = e.steps.map(({ message: i, ...n }) => {
|
|
321
385
|
const r = {
|
|
322
|
-
...
|
|
323
|
-
message: { ...
|
|
386
|
+
...n,
|
|
387
|
+
message: { ...i },
|
|
324
388
|
markAsSeen() {
|
|
325
389
|
if (!this.message.seen_at)
|
|
326
390
|
return t.markAsSeen(s, this);
|
|
@@ -334,39 +398,43 @@ class O {
|
|
|
334
398
|
}
|
|
335
399
|
};
|
|
336
400
|
return r.markAsSeen = r.markAsSeen.bind(r), r.markAsInteracted = r.markAsInteracted.bind(r), r.markAsArchived = r.markAsArchived.bind(r), r;
|
|
337
|
-
}), s.
|
|
338
|
-
...
|
|
339
|
-
pattern: new
|
|
401
|
+
}), s.activation_url_patterns = e.activation_url_patterns.map((i) => ({
|
|
402
|
+
...i,
|
|
403
|
+
pattern: new b({ pathname: i.pathname })
|
|
340
404
|
})), s;
|
|
341
405
|
}
|
|
342
406
|
buildQueryParams(e = {}) {
|
|
343
|
-
const t = {
|
|
344
|
-
|
|
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(
|
|
345
413
|
Object.entries(t).filter(
|
|
346
|
-
([n,
|
|
414
|
+
([n, r]) => r != null
|
|
347
415
|
)
|
|
348
416
|
);
|
|
349
|
-
return
|
|
417
|
+
return i = i.data ? { ...i, data: JSON.stringify(i.data) } : i, i;
|
|
350
418
|
}
|
|
351
419
|
formatQueryKey(e) {
|
|
352
420
|
const s = Object.keys(e).sort().map(
|
|
353
|
-
(
|
|
354
|
-
).join("&"),
|
|
355
|
-
return s ? `${
|
|
421
|
+
(n) => `${encodeURIComponent(n)}=${encodeURIComponent(e[n])}`
|
|
422
|
+
).join("&"), i = K(this.knock.userId);
|
|
423
|
+
return s ? `${i}?${s}` : i;
|
|
356
424
|
}
|
|
357
425
|
setStepMessageAttrs(e, t, s) {
|
|
358
|
-
let
|
|
359
|
-
return s.archived_at && this.clearGroupStage(), this.store.setState((
|
|
360
|
-
const r =
|
|
361
|
-
if (!r) return
|
|
362
|
-
const o = r.steps.map((
|
|
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));
|
|
363
431
|
r.steps = o;
|
|
364
|
-
const
|
|
365
|
-
...
|
|
432
|
+
const u = { ...n.guides, [r.key]: r }, c = s.archived_at && !r.bypass_global_group_limit ? {
|
|
433
|
+
...n.guideGroupDisplayLogs,
|
|
366
434
|
[p]: s.archived_at
|
|
367
|
-
} :
|
|
368
|
-
return { ...
|
|
369
|
-
}),
|
|
435
|
+
} : n.guideGroupDisplayLogs;
|
|
436
|
+
return { ...n, guides: u, guideGroupDisplayLogs: c };
|
|
437
|
+
}), i;
|
|
370
438
|
}
|
|
371
439
|
buildEngagementEventBaseParams(e, t) {
|
|
372
440
|
return {
|
|
@@ -381,47 +449,59 @@ class O {
|
|
|
381
449
|
this.patchClosedGroupStage();
|
|
382
450
|
const t = this.localCopy(e.guide);
|
|
383
451
|
this.store.setState((s) => {
|
|
384
|
-
const
|
|
385
|
-
return { ...s, guides:
|
|
452
|
+
const i = { ...s.guides, [t.key]: t };
|
|
453
|
+
return { ...s, guides: i };
|
|
386
454
|
});
|
|
387
455
|
}
|
|
388
456
|
removeGuide({ data: e }) {
|
|
389
457
|
this.patchClosedGroupStage(), this.store.setState((t) => {
|
|
390
|
-
const { [e.guide.key]: s, ...
|
|
391
|
-
return { ...t, guides:
|
|
458
|
+
const { [e.guide.key]: s, ...i } = t.guides;
|
|
459
|
+
return { ...t, guides: i };
|
|
392
460
|
});
|
|
393
461
|
}
|
|
394
462
|
addOrReplaceGuideGroup({
|
|
395
463
|
data: e
|
|
396
464
|
}) {
|
|
397
465
|
this.patchClosedGroupStage(), this.store.setState((t) => {
|
|
398
|
-
const s = [e.guide_group],
|
|
466
|
+
const s = [e.guide_group], i = e.guide_group.display_sequence_unthrottled || [], n = e.guide_group.display_sequence_throttled || [];
|
|
399
467
|
let r = t.guides;
|
|
400
|
-
return r =
|
|
401
|
-
if (!o[
|
|
402
|
-
const
|
|
403
|
-
return { ...o, [
|
|
404
|
-
}, r), r =
|
|
405
|
-
if (!o[
|
|
406
|
-
const
|
|
407
|
-
return { ...o, [
|
|
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 };
|
|
408
476
|
}, r), { ...t, guides: r, guideGroups: s };
|
|
409
477
|
});
|
|
410
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
|
+
}
|
|
411
491
|
listenForLocationChangesFromWindow() {
|
|
412
492
|
const e = l();
|
|
413
493
|
if (e != null && e.history) {
|
|
414
494
|
e.addEventListener("popstate", this.handleLocationChange), e.addEventListener("hashchange", this.handleLocationChange);
|
|
415
495
|
const t = e.history.pushState, s = e.history.replaceState;
|
|
416
496
|
e.history.pushState = new Proxy(t, {
|
|
417
|
-
apply: (
|
|
418
|
-
Reflect.apply(
|
|
497
|
+
apply: (i, n, r) => {
|
|
498
|
+
Reflect.apply(i, n, r), setTimeout(() => {
|
|
419
499
|
this.handleLocationChange();
|
|
420
500
|
}, 0);
|
|
421
501
|
}
|
|
422
502
|
}), e.history.replaceState = new Proxy(s, {
|
|
423
|
-
apply: (
|
|
424
|
-
Reflect.apply(
|
|
503
|
+
apply: (i, n, r) => {
|
|
504
|
+
Reflect.apply(i, n, r), setTimeout(() => {
|
|
425
505
|
this.handleLocationChange();
|
|
426
506
|
}, 0);
|
|
427
507
|
}
|
|
@@ -437,7 +517,8 @@ class O {
|
|
|
437
517
|
}
|
|
438
518
|
}
|
|
439
519
|
export {
|
|
440
|
-
|
|
441
|
-
|
|
520
|
+
k as DEBUG_QUERY_PARAMS,
|
|
521
|
+
j as KnockGuideClient,
|
|
522
|
+
K as guidesApiRootPath
|
|
442
523
|
};
|
|
443
524
|
//# sourceMappingURL=client.mjs.map
|