@guidelytech/sdk-core 0.9.0 → 0.10.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/README.md +15 -4
- package/dist/{capture-C3faAYb7.d.cts → capture-369s4YYT.d.ts} +2 -1
- package/dist/{capture-Dqd7up2n.d.ts → capture-DVJyQ2JZ.d.cts} +2 -1
- package/dist/capture.cjs +2 -0
- package/dist/capture.cjs.map +1 -1
- package/dist/capture.d.cts +3 -2
- package/dist/capture.d.ts +3 -2
- package/dist/capture.js +4 -6
- package/dist/capture.js.map +1 -1
- package/dist/chunk-C4WWSF67.js +374 -0
- package/dist/chunk-C4WWSF67.js.map +1 -0
- package/dist/{chunk-544KSOC3.js → chunk-GDJB466J.js} +115 -18
- package/dist/chunk-GDJB466J.js.map +1 -0
- package/dist/headless.cjs +275 -40
- package/dist/headless.cjs.map +1 -1
- package/dist/headless.d.cts +43 -3
- package/dist/headless.d.ts +43 -3
- package/dist/headless.js +14 -8
- package/dist/health-DFHUstWd.d.cts +88 -0
- package/dist/health-DFHUstWd.d.ts +88 -0
- package/dist/{http-47tiAlOM.d.ts → http-D0dCcpLN.d.cts} +10 -35
- package/dist/{http-47tiAlOM.d.cts → http-DJd8jRhK.d.ts} +10 -35
- package/dist/index.cjs +342 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -5
- package/dist/index.d.ts +10 -5
- package/dist/index.js +71 -32
- package/dist/index.js.map +1 -1
- package/dist/recorder.cjs +70 -9
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts +9 -0
- package/dist/recorder.d.ts +9 -0
- package/dist/recorder.js +57 -11
- package/dist/recorder.js.map +1 -1
- package/dist/{types-DnJW_4ck.d.ts → types-B5ecgHUV.d.cts} +10 -3
- package/dist/{types-zM5e3loY.d.cts → types-BtPovimB.d.ts} +10 -3
- package/package.json +4 -4
- package/dist/chunk-544KSOC3.js.map +0 -1
- package/dist/chunk-AKNE7D5M.js +0 -160
- package/dist/chunk-AKNE7D5M.js.map +0 -1
- package/dist/chunk-CYAG6ZYX.js +0 -85
- package/dist/chunk-CYAG6ZYX.js.map +0 -1
- package/dist/chunk-GDF6RCHQ.js +0 -209
- package/dist/chunk-GDF6RCHQ.js.map +0 -1
- package/dist/types-DbKQPvFt.d.cts +0 -238
- package/dist/types-DqhNl5Am.d.ts +0 -238
- package/dist/types-RyeRQd9f.d.ts +0 -226
- package/dist/types-d4eOerxi.d.cts +0 -226
package/dist/index.d.cts
CHANGED
|
@@ -4,14 +4,15 @@ export { AppSnapshot, AutocaptureSettings, ExceptionProperties, GuideConfig, Gui
|
|
|
4
4
|
import { FlagsClient, JsonValue, FlagValue, FlagDetails } from '@guidelytech/flags';
|
|
5
5
|
export { Attributes, EvaluationResult, FlagDetails, FlagsBootstrap, FlagsClient, FlagsClientOptions, FlagsPayload, JsonValue } from '@guidelytech/flags';
|
|
6
6
|
import { MessengerTab } from '@guidelytech/guide-runtime/messenger';
|
|
7
|
-
import { k as GuidelyOptions, c as GuidelyAccount, a as ConsentState, C as ChecklistProgressState, l as GuidelyEvents, e as GuidelyUser, G as GuideLocalState, S as SessionState } from './types-
|
|
8
|
-
export { E as EventQueue, b as EventQueueOptions, m as GuideStepInfo, d as GuidelyEnvironment, n as GuidelyEventName, P as PersistedState, f as areMutuallyExclusive, i as isExclusiveGuide, h as isFrequencyEligible, j as isWithinSchedule } from './types-
|
|
9
|
-
export {
|
|
10
|
-
export { C as CaptureMarker, a as CaptureOutgoingMessage } from './capture-
|
|
7
|
+
import { k as GuidelyOptions, c as GuidelyAccount, a as ConsentState, C as ChecklistProgressState, l as GuidelyEvents, e as GuidelyUser, G as GuideLocalState, S as SessionState } from './types-B5ecgHUV.cjs';
|
|
8
|
+
export { E as EventQueue, b as EventQueueOptions, m as GuideStepInfo, d as GuidelyEnvironment, n as GuidelyEventName, P as PersistedState, f as areMutuallyExclusive, i as isExclusiveGuide, h as isFrequencyEligible, j as isWithinSchedule } from './types-B5ecgHUV.cjs';
|
|
9
|
+
export { a as KEYS, K as KeyValueStore, c as StorageKind, d as createStorage } from './health-DFHUstWd.cjs';
|
|
10
|
+
export { C as CaptureMarker, a as CaptureOutgoingMessage } from './capture-DVJyQ2JZ.cjs';
|
|
11
11
|
export { CAPTURE_PARAM } from '@guidelytech/shared/runtime';
|
|
12
|
+
import './http-D0dCcpLN.cjs';
|
|
12
13
|
|
|
13
14
|
declare const SDK_NAME = "@guidelytech/sdk-core";
|
|
14
|
-
declare const SDK_VERSION = "0.
|
|
15
|
+
declare const SDK_VERSION = "0.10.0";
|
|
15
16
|
declare const DEFAULT_API_URL = "https://api.guidely.app";
|
|
16
17
|
/**
|
|
17
18
|
* Framework-independent Guidely client. Create one per page with {@link createGuidely} or
|
|
@@ -24,6 +25,8 @@ declare class GuidelyClient {
|
|
|
24
25
|
private readonly sessionStore;
|
|
25
26
|
private readonly emitter;
|
|
26
27
|
private readonly queue;
|
|
28
|
+
/** Survey answers and guide/checklist progress, kept until the server accepts them. */
|
|
29
|
+
private readonly outbox;
|
|
27
30
|
private config;
|
|
28
31
|
private etag;
|
|
29
32
|
private anonymousId;
|
|
@@ -85,6 +88,8 @@ declare class GuidelyClient {
|
|
|
85
88
|
private wireErrorListeners;
|
|
86
89
|
/** Re-fetches the published config and re-evaluates triggers. */
|
|
87
90
|
refresh(): Promise<void>;
|
|
91
|
+
/** Re-renders after a config change (refresh, or a config that arrived after start). */
|
|
92
|
+
private applyConfigChange;
|
|
88
93
|
/** Tears everything down: guides, widgets, listeners, timers, host element. Re-init is allowed via a new client. */
|
|
89
94
|
destroy(): void;
|
|
90
95
|
/** Identifies the end user and loads server-held state (audiences, guide history, checklist progress). */
|
package/dist/index.d.ts
CHANGED
|
@@ -4,14 +4,15 @@ export { AppSnapshot, AutocaptureSettings, ExceptionProperties, GuideConfig, Gui
|
|
|
4
4
|
import { FlagsClient, JsonValue, FlagValue, FlagDetails } from '@guidelytech/flags';
|
|
5
5
|
export { Attributes, EvaluationResult, FlagDetails, FlagsBootstrap, FlagsClient, FlagsClientOptions, FlagsPayload, JsonValue } from '@guidelytech/flags';
|
|
6
6
|
import { MessengerTab } from '@guidelytech/guide-runtime/messenger';
|
|
7
|
-
import { k as GuidelyOptions, c as GuidelyAccount, a as ConsentState, C as ChecklistProgressState, l as GuidelyEvents, e as GuidelyUser, G as GuideLocalState, S as SessionState } from './types-
|
|
8
|
-
export { E as EventQueue, b as EventQueueOptions, m as GuideStepInfo, d as GuidelyEnvironment, n as GuidelyEventName, P as PersistedState, f as areMutuallyExclusive, i as isExclusiveGuide, h as isFrequencyEligible, j as isWithinSchedule } from './types-
|
|
9
|
-
export {
|
|
10
|
-
export { C as CaptureMarker, a as CaptureOutgoingMessage } from './capture-
|
|
7
|
+
import { k as GuidelyOptions, c as GuidelyAccount, a as ConsentState, C as ChecklistProgressState, l as GuidelyEvents, e as GuidelyUser, G as GuideLocalState, S as SessionState } from './types-BtPovimB.js';
|
|
8
|
+
export { E as EventQueue, b as EventQueueOptions, m as GuideStepInfo, d as GuidelyEnvironment, n as GuidelyEventName, P as PersistedState, f as areMutuallyExclusive, i as isExclusiveGuide, h as isFrequencyEligible, j as isWithinSchedule } from './types-BtPovimB.js';
|
|
9
|
+
export { a as KEYS, K as KeyValueStore, c as StorageKind, d as createStorage } from './health-DFHUstWd.js';
|
|
10
|
+
export { C as CaptureMarker, a as CaptureOutgoingMessage } from './capture-369s4YYT.js';
|
|
11
11
|
export { CAPTURE_PARAM } from '@guidelytech/shared/runtime';
|
|
12
|
+
import './http-DJd8jRhK.js';
|
|
12
13
|
|
|
13
14
|
declare const SDK_NAME = "@guidelytech/sdk-core";
|
|
14
|
-
declare const SDK_VERSION = "0.
|
|
15
|
+
declare const SDK_VERSION = "0.10.0";
|
|
15
16
|
declare const DEFAULT_API_URL = "https://api.guidely.app";
|
|
16
17
|
/**
|
|
17
18
|
* Framework-independent Guidely client. Create one per page with {@link createGuidely} or
|
|
@@ -24,6 +25,8 @@ declare class GuidelyClient {
|
|
|
24
25
|
private readonly sessionStore;
|
|
25
26
|
private readonly emitter;
|
|
26
27
|
private readonly queue;
|
|
28
|
+
/** Survey answers and guide/checklist progress, kept until the server accepts them. */
|
|
29
|
+
private readonly outbox;
|
|
27
30
|
private config;
|
|
28
31
|
private etag;
|
|
29
32
|
private anonymousId;
|
|
@@ -85,6 +88,8 @@ declare class GuidelyClient {
|
|
|
85
88
|
private wireErrorListeners;
|
|
86
89
|
/** Re-fetches the published config and re-evaluates triggers. */
|
|
87
90
|
refresh(): Promise<void>;
|
|
91
|
+
/** Re-renders after a config change (refresh, or a config that arrived after start). */
|
|
92
|
+
private applyConfigChange;
|
|
88
93
|
/** Tears everything down: guides, widgets, listeners, timers, host element. Re-init is allowed via a new client. */
|
|
89
94
|
destroy(): void;
|
|
90
95
|
/** Identifies the end user and loads server-held state (audiences, guide history, checklist progress). */
|
package/dist/index.js
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Emitter,
|
|
3
3
|
EventQueue,
|
|
4
|
+
Outbox,
|
|
4
5
|
areMutuallyExclusive,
|
|
5
6
|
dismissedAfterMerge,
|
|
6
7
|
isExclusiveGuide,
|
|
7
8
|
isFrequencyEligible,
|
|
8
9
|
isWithinSchedule
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-GDJB466J.js";
|
|
10
11
|
import {
|
|
12
|
+
Api,
|
|
11
13
|
KEYS,
|
|
14
|
+
__publicField,
|
|
12
15
|
createStorage,
|
|
16
|
+
postWithRetry,
|
|
13
17
|
readJson,
|
|
14
18
|
writeJson
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import {
|
|
17
|
-
Api,
|
|
18
|
-
__publicField,
|
|
19
|
-
postWithRetry
|
|
20
|
-
} from "./chunk-AKNE7D5M.js";
|
|
19
|
+
} from "./chunk-C4WWSF67.js";
|
|
21
20
|
|
|
22
21
|
// src/client.ts
|
|
23
22
|
import { evaluateRules, randomId, rolloutBucket, sanitizeProperties, supportsPlatform } from "@guidelytech/shared/runtime";
|
|
24
23
|
import {
|
|
24
|
+
closestComposed as closestComposed3,
|
|
25
|
+
composedTarget,
|
|
25
26
|
destroyHost,
|
|
26
27
|
isChecklistComplete,
|
|
27
28
|
renderChecklist,
|
|
@@ -35,7 +36,7 @@ import { createScope } from "@guidelytech/guide-runtime";
|
|
|
35
36
|
import { createFlagsClient } from "@guidelytech/flags";
|
|
36
37
|
|
|
37
38
|
// src/authoring.ts
|
|
38
|
-
import { highlightSelectors, previewStep, runGuide, startAuthoring } from "@guidelytech/guide-runtime";
|
|
39
|
+
import { closestComposed, highlightSelectors, previewStep, runGuide, startAuthoring } from "@guidelytech/guide-runtime";
|
|
39
40
|
|
|
40
41
|
// src/snapshot.ts
|
|
41
42
|
var MAX_SNAPSHOT_BYTES = 6 * 1024 * 1024;
|
|
@@ -199,7 +200,7 @@ var AuthoringBridge = class {
|
|
|
199
200
|
masked(el) {
|
|
200
201
|
return this.opts.maskSelectors.some((sel) => {
|
|
201
202
|
try {
|
|
202
|
-
return !!el
|
|
203
|
+
return !!closestComposed(el, sel);
|
|
203
204
|
} catch {
|
|
204
205
|
return false;
|
|
205
206
|
}
|
|
@@ -380,7 +381,7 @@ function takeCaptureToken(sessionStore) {
|
|
|
380
381
|
var loadCapture = async () => (await import("./capture.js")).capture;
|
|
381
382
|
|
|
382
383
|
// src/autocapture.ts
|
|
383
|
-
import { isGuidelyElement, isStableId } from "@guidelytech/guide-runtime";
|
|
384
|
+
import { closestComposed as closestComposed2, isGuidelyElement, isStableId, SHADOW_SEPARATOR, shadowHostChain } from "@guidelytech/guide-runtime";
|
|
384
385
|
var INTERACTIVE_SELECTOR = "a,button,input[type=button],input[type=submit],input[type=reset],input[type=checkbox],input[type=radio],select,summary,label,[role=button],[role=link],[role=tab],[role=menuitem],[role=checkbox],[role=switch],[role=option],[onclick],[data-guidely-track]";
|
|
385
386
|
var DEFAULT_MASK_SELECTORS = ["[data-guidely-mask]", ".guidely-mask"];
|
|
386
387
|
var PREFERRED_ATTRS = ["data-testid", "data-test-id", "data-test", "data-cy", "data-qa", "data-guidely-track", "data-tour"];
|
|
@@ -400,11 +401,11 @@ function validSelectors(list) {
|
|
|
400
401
|
return out;
|
|
401
402
|
}
|
|
402
403
|
function isIgnoredElement(el) {
|
|
403
|
-
return isGuidelyElement(el) || !!el
|
|
404
|
+
return isGuidelyElement(el) || !!closestComposed2(el, "[data-guidely-ignore]");
|
|
404
405
|
}
|
|
405
406
|
function interactiveElement(target) {
|
|
406
407
|
try {
|
|
407
|
-
return target
|
|
408
|
+
return closestComposed2(target, INTERACTIVE_SELECTOR);
|
|
408
409
|
} catch {
|
|
409
410
|
return null;
|
|
410
411
|
}
|
|
@@ -415,14 +416,19 @@ function esc(value) {
|
|
|
415
416
|
}
|
|
416
417
|
var attr = (tag, name, value) => value ? `${tag}[${name}="${value.replace(/["\\]/g, "\\$&")}"]` : `${tag}[${name}]`;
|
|
417
418
|
function elementSelector(el) {
|
|
419
|
+
const own = ownSelector(el);
|
|
420
|
+
const chain = shadowHostChain(el);
|
|
421
|
+
return (chain ? chain + SHADOW_SEPARATOR + own : own).slice(0, 300);
|
|
422
|
+
}
|
|
423
|
+
function ownSelector(el) {
|
|
418
424
|
const tag = el.tagName.toLowerCase();
|
|
419
425
|
if (el.id && isStableId(el.id)) return `#${esc(el.id)}`;
|
|
420
|
-
for (const name of PREFERRED_ATTRS) if (el.hasAttribute(name)) return attr(tag, name, el.getAttribute(name) || "")
|
|
426
|
+
for (const name of PREFERRED_ATTRS) if (el.hasAttribute(name)) return attr(tag, name, el.getAttribute(name) || "");
|
|
421
427
|
for (const a of Array.from(el.attributes)) {
|
|
422
|
-
if (a.name.startsWith("data-") && !NOISY_DATA_ATTR.test(a.name) && a.value && a.value.length <= 60) return attr(tag, a.name, a.value)
|
|
428
|
+
if (a.name.startsWith("data-") && !NOISY_DATA_ATTR.test(a.name) && a.value && a.value.length <= 60) return attr(tag, a.name, a.value);
|
|
423
429
|
}
|
|
424
430
|
const label = el.getAttribute("aria-label");
|
|
425
|
-
if (label && label.length <= 80) return attr(tag, "aria-label", label)
|
|
431
|
+
if (label && label.length <= 80) return attr(tag, "aria-label", label);
|
|
426
432
|
const parts = [];
|
|
427
433
|
let cur = el;
|
|
428
434
|
while (cur && parts.length < 4) {
|
|
@@ -438,12 +444,12 @@ function elementSelector(el) {
|
|
|
438
444
|
parts.unshift(same.length > 1 ? `${t}:nth-of-type(${same.indexOf(node) + 1})` : t);
|
|
439
445
|
cur = parent;
|
|
440
446
|
}
|
|
441
|
-
return
|
|
447
|
+
return parts.join(" > ") || tag;
|
|
442
448
|
}
|
|
443
449
|
function matches(el, selector, deep) {
|
|
444
450
|
if (!selector) return false;
|
|
445
451
|
try {
|
|
446
|
-
return !!el
|
|
452
|
+
return !!closestComposed2(el, selector) || deep && !!el.querySelector(selector);
|
|
447
453
|
} catch {
|
|
448
454
|
return false;
|
|
449
455
|
}
|
|
@@ -461,7 +467,7 @@ function elementText(el, mask, maskAll) {
|
|
|
461
467
|
return text ? text.slice(0, 100) : void 0;
|
|
462
468
|
}
|
|
463
469
|
function linkHref(el) {
|
|
464
|
-
const a = el
|
|
470
|
+
const a = closestComposed2(el, "a[href]");
|
|
465
471
|
if (!a) return void 0;
|
|
466
472
|
try {
|
|
467
473
|
const u = new URL(a.getAttribute("href") || "", location.href);
|
|
@@ -1028,11 +1034,22 @@ var loadRecorder = async () => (await import("./recorder.js")).recorder;
|
|
|
1028
1034
|
|
|
1029
1035
|
// src/client.ts
|
|
1030
1036
|
var SDK_NAME = "@guidelytech/sdk-core";
|
|
1031
|
-
var SDK_VERSION = "0.
|
|
1037
|
+
var SDK_VERSION = "0.10.0";
|
|
1032
1038
|
var DEFAULT_API_URL = "https://api.guidely.app";
|
|
1033
1039
|
var PAGE_SCOPED = /* @__PURE__ */ new Set(["page_load", "url_match", "element_click", "element_visible", "delay"]);
|
|
1034
1040
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
1035
1041
|
var MAX_SESSION_EXCEPTIONS = 100;
|
|
1042
|
+
var CACHED_START_MS = 1500;
|
|
1043
|
+
function settlesWithin(promise, ms) {
|
|
1044
|
+
return new Promise((resolve) => {
|
|
1045
|
+
const timer = setTimeout(() => resolve(false), ms);
|
|
1046
|
+
const done = () => {
|
|
1047
|
+
clearTimeout(timer);
|
|
1048
|
+
resolve(true);
|
|
1049
|
+
};
|
|
1050
|
+
promise.then(done, done);
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1036
1053
|
function isBrowser() {
|
|
1037
1054
|
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
1038
1055
|
}
|
|
@@ -1053,6 +1070,8 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1053
1070
|
__publicField(this, "sessionStore");
|
|
1054
1071
|
__publicField(this, "emitter");
|
|
1055
1072
|
__publicField(this, "queue");
|
|
1073
|
+
/** Survey answers and guide/checklist progress, kept until the server accepts them. */
|
|
1074
|
+
__publicField(this, "outbox");
|
|
1056
1075
|
__publicField(this, "config", null);
|
|
1057
1076
|
__publicField(this, "etag", null);
|
|
1058
1077
|
__publicField(this, "anonymousId");
|
|
@@ -1152,6 +1171,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1152
1171
|
store: this.store,
|
|
1153
1172
|
storageKey: KEYS.queue(this.options.projectId),
|
|
1154
1173
|
enabled: () => this.analyticsEnabled(),
|
|
1174
|
+
health: this.api.health,
|
|
1155
1175
|
send: async (events) => {
|
|
1156
1176
|
const res = await this.api.post("/events", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }, { keepalive: true });
|
|
1157
1177
|
return { ok: res.ok, retry: !(res.status >= 400 && res.status < 500 && res.status !== 429) };
|
|
@@ -1159,6 +1179,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1159
1179
|
beacon: (events) => this.api.beacon("/events", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }),
|
|
1160
1180
|
onError: (err) => this.reportError(err)
|
|
1161
1181
|
});
|
|
1182
|
+
this.outbox = new Outbox({ api: this.api, store: this.store, storageKey: KEYS.outbox(this.options.projectId), health: this.api.health });
|
|
1162
1183
|
if (options.user) this.user = { ...options.user };
|
|
1163
1184
|
this.flags = this.createFlags(options.flags);
|
|
1164
1185
|
}
|
|
@@ -1216,12 +1237,15 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1216
1237
|
const cached = readJson(this.store, KEYS.config(this.options.projectId), null);
|
|
1217
1238
|
this.etag = this.store.get(KEYS.etag(this.options.projectId));
|
|
1218
1239
|
if (cached && cached.guides) this.config = webOnly(cached);
|
|
1219
|
-
|
|
1240
|
+
const before = this.config?.configVersion;
|
|
1241
|
+
const fresh = this.fetchConfig();
|
|
1242
|
+
if (!this.config) await fresh;
|
|
1243
|
+
else if (!await settlesWithin(fresh, CACHED_START_MS)) void fresh.then(() => this.applyConfigChange(before));
|
|
1220
1244
|
if (this.destroyed) return;
|
|
1221
1245
|
this.wireListeners();
|
|
1222
1246
|
if (!this.identitySettled) {
|
|
1223
|
-
|
|
1224
|
-
|
|
1247
|
+
const known = this.options.user ?? (this.user?.id ? this.user : null);
|
|
1248
|
+
if (known) await settlesWithin(this.identify(known.id, known.traits, known.account), CACHED_START_MS);
|
|
1225
1249
|
}
|
|
1226
1250
|
if (this.destroyed) return;
|
|
1227
1251
|
this.isReady = true;
|
|
@@ -1326,7 +1350,12 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1326
1350
|
win.removeEventListener("scroll", onScroll);
|
|
1327
1351
|
doc.removeEventListener("keydown", onKey, true);
|
|
1328
1352
|
});
|
|
1329
|
-
const refresh = setInterval(() =>
|
|
1353
|
+
const refresh = setInterval(() => {
|
|
1354
|
+
if (this.api.health.canSend()) void this.refresh();
|
|
1355
|
+
}, this.options.configRefreshMs);
|
|
1356
|
+
const onOnline = () => this.api.health.online();
|
|
1357
|
+
win.addEventListener("online", onOnline);
|
|
1358
|
+
this.cleanups.push(() => win.removeEventListener("online", onOnline));
|
|
1330
1359
|
this.cleanups.push(() => clearInterval(refresh));
|
|
1331
1360
|
const poll = setInterval(() => {
|
|
1332
1361
|
if (!this.isReady || !this.config || this.editing() || doc.visibilityState === "hidden") return;
|
|
@@ -1359,6 +1388,11 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1359
1388
|
if (this.destroyed) return;
|
|
1360
1389
|
const before = this.config?.configVersion;
|
|
1361
1390
|
await this.fetchConfig();
|
|
1391
|
+
this.applyConfigChange(before);
|
|
1392
|
+
}
|
|
1393
|
+
/** Re-renders after a config change (refresh, or a config that arrived after start). */
|
|
1394
|
+
applyConfigChange(before) {
|
|
1395
|
+
if (this.destroyed || !this.isReady) return;
|
|
1362
1396
|
if (this.config && this.config.configVersion !== before) {
|
|
1363
1397
|
this.renderPersistentWidgets();
|
|
1364
1398
|
this.evaluate("ready");
|
|
@@ -1393,6 +1427,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1393
1427
|
this.replay = null;
|
|
1394
1428
|
this.queue.flushSync();
|
|
1395
1429
|
this.queue.destroy();
|
|
1430
|
+
this.outbox.destroy();
|
|
1396
1431
|
this.flags.destroy();
|
|
1397
1432
|
this.emitter.clear();
|
|
1398
1433
|
destroyHost();
|
|
@@ -1595,7 +1630,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1595
1630
|
if (changed) void this.queue.flush();
|
|
1596
1631
|
}
|
|
1597
1632
|
handleDocumentClick(e) {
|
|
1598
|
-
const target = e
|
|
1633
|
+
const target = composedTarget(e);
|
|
1599
1634
|
if (!target || typeof target.closest !== "function") return;
|
|
1600
1635
|
this.autocaptureClick(e, target);
|
|
1601
1636
|
this.completeChecklistTasksBy("click", target);
|
|
@@ -1690,7 +1725,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1690
1725
|
}
|
|
1691
1726
|
/** Bins one pointer sample into the heatmap buffer. Not session activity. */
|
|
1692
1727
|
sampleMove(e) {
|
|
1693
|
-
const target = e
|
|
1728
|
+
const target = composedTarget(e);
|
|
1694
1729
|
if (document.visibilityState === "hidden" || !target?.closest || !this.autocaptureOn("mouseMovement") || isIgnoredElement(target)) return;
|
|
1695
1730
|
const url = location.href;
|
|
1696
1731
|
if (this.heatmap.url !== url) this.flushHeatmap();
|
|
@@ -1815,7 +1850,9 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1815
1850
|
this.persistSession();
|
|
1816
1851
|
this.replay?.stop({ discard: true });
|
|
1817
1852
|
},
|
|
1818
|
-
onError: (err) => this.reportError(err)
|
|
1853
|
+
onError: (err) => this.reportError(err),
|
|
1854
|
+
health: this.api.health,
|
|
1855
|
+
stash: this.sessionStore
|
|
1819
1856
|
});
|
|
1820
1857
|
this.syncReplay();
|
|
1821
1858
|
},
|
|
@@ -1905,7 +1942,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
1905
1942
|
case "element_click":
|
|
1906
1943
|
if (reason !== "click" || !t.value || !detail.target) return false;
|
|
1907
1944
|
try {
|
|
1908
|
-
return !!detail.target
|
|
1945
|
+
return !!closestComposed3(detail.target, t.value);
|
|
1909
1946
|
} catch {
|
|
1910
1947
|
return false;
|
|
1911
1948
|
}
|
|
@@ -2056,7 +2093,9 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
2056
2093
|
if (reason === "completed") this.completeChecklistTasksBy("guide_completed", guide);
|
|
2057
2094
|
}
|
|
2058
2095
|
syncGuideState(guideId, update) {
|
|
2059
|
-
|
|
2096
|
+
const body = { anonymousId: this.anonymousId, userId: this.user?.id || null, updates: [{ guideId, ...update }] };
|
|
2097
|
+
if (update.impression) void postWithRetry(this.api, "/guide-state", body);
|
|
2098
|
+
else this.outbox.add(`guide:${guideId}:${update.completed ? "completed" : "dismissed"}:${this.anonymousId}`, "/guide-state", body);
|
|
2060
2099
|
}
|
|
2061
2100
|
show(guide, manual, stepId) {
|
|
2062
2101
|
try {
|
|
@@ -2184,7 +2223,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
2184
2223
|
this.persistState();
|
|
2185
2224
|
this.recordEnd(guide, "completed");
|
|
2186
2225
|
this.enqueue("survey_submitted", { guideId: guide.id, guideVersion: guide.version, properties: { responseId } });
|
|
2187
|
-
|
|
2226
|
+
this.outbox.add(`survey:${responseId}`, `/surveys/${encodeURIComponent(guide.id)}/responses`, { anonymousId: this.anonymousId, userId: this.user?.id || null, accountId: this.user?.account?.id || null, guideVersion: guide.version, answers, responseId });
|
|
2188
2227
|
this.emitter.emit("survey:submit", { guide, answers, responseId });
|
|
2189
2228
|
this.emitter.emit("guide:complete", guide);
|
|
2190
2229
|
widget.showThankYou();
|
|
@@ -2373,7 +2412,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
2373
2412
|
}
|
|
2374
2413
|
this.persistState();
|
|
2375
2414
|
this.widgets.get(guide.id)?.checklist?.setProgress(this.getChecklistProgress(guide.id));
|
|
2376
|
-
|
|
2415
|
+
this.outbox.add(`checklist:${guide.id}:progress:${this.anonymousId}`, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, completed: !!progress.completedAt });
|
|
2377
2416
|
this.emitter.emit("checklist:task", { guide, task, progress: this.getChecklistProgress(guide.id) });
|
|
2378
2417
|
if (complete) {
|
|
2379
2418
|
this.emitter.emit("checklist:complete", guide);
|
|
@@ -2393,7 +2432,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
2393
2432
|
else if (kind === "guide_completed") hit = value.id === task.completionValue || value.key === task.completionValue;
|
|
2394
2433
|
else if (kind === "click") {
|
|
2395
2434
|
try {
|
|
2396
|
-
hit = !!value
|
|
2435
|
+
hit = !!closestComposed3(value, task.completionValue);
|
|
2397
2436
|
} catch {
|
|
2398
2437
|
hit = false;
|
|
2399
2438
|
}
|
|
@@ -2413,7 +2452,7 @@ var GuidelyClient = class _GuidelyClient {
|
|
|
2413
2452
|
progress.dismissedAt = nowIso();
|
|
2414
2453
|
this.persistState();
|
|
2415
2454
|
this.enqueue("checklist_dismissed", { guideId: guide.id, guideVersion: guide.version });
|
|
2416
|
-
|
|
2455
|
+
this.outbox.add(`checklist:${guide.id}:dismissed:${this.anonymousId}`, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, dismissed: true });
|
|
2417
2456
|
this.widgets.get(guide.id)?.destroy();
|
|
2418
2457
|
this.widgets.delete(guide.id);
|
|
2419
2458
|
}
|