@coframe/sdk 1.1.39 → 1.1.41
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/dist/pkg/cf.cjs.js +271 -20
- package/dist/pkg/cf.esm.mjs +271 -20
- package/dist/pkg/types/index.d.ts +5 -0
- package/dist/pkg/types/react.d.ts +5 -0
- package/dist/pkg/types/server.d.ts +5 -0
- package/package.json +1 -1
package/dist/pkg/cf.cjs.js
CHANGED
|
@@ -1125,7 +1125,7 @@ function warnEventsNotSent() {
|
|
|
1125
1125
|
}
|
|
1126
1126
|
}
|
|
1127
1127
|
|
|
1128
|
-
const SDK_VERSION = '2.
|
|
1128
|
+
const SDK_VERSION = '2.9.0';
|
|
1129
1129
|
const queuedEvents = [];
|
|
1130
1130
|
const queuedMonitoringEvents = [];
|
|
1131
1131
|
const queuedSessions = [];
|
|
@@ -1230,7 +1230,7 @@ function flushQueuedEvents(projectId) {
|
|
|
1230
1230
|
queuedSessions.length = 0;
|
|
1231
1231
|
}
|
|
1232
1232
|
}
|
|
1233
|
-
function queueEvent(coframe, sessionInfo) {
|
|
1233
|
+
function queueEvent(coframe, sessionInfo, heatmap) {
|
|
1234
1234
|
const { projectId, sessionId, eventType, orgId, userToken } = sessionInfo;
|
|
1235
1235
|
const data = {
|
|
1236
1236
|
type: eventType,
|
|
@@ -1242,13 +1242,19 @@ function queueEvent(coframe, sessionInfo) {
|
|
|
1242
1242
|
user_token: userToken,
|
|
1243
1243
|
};
|
|
1244
1244
|
const seg = sessionInfo.personalizationHeaders;
|
|
1245
|
-
const metadata = seg
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1245
|
+
const metadata = seg
|
|
1246
|
+
? { personalization_headers: { ...seg } }
|
|
1247
|
+
: {};
|
|
1248
|
+
if (heatmap === null || heatmap === void 0 ? void 0 : heatmap.hm)
|
|
1249
|
+
metadata.hm = heatmap.hm;
|
|
1250
|
+
data.content =
|
|
1251
|
+
eventType === 'page_view'
|
|
1252
|
+
? {
|
|
1253
|
+
universal_selector: {},
|
|
1254
|
+
metadata,
|
|
1255
|
+
screen_size: { width: window.innerWidth, height: window.innerHeight },
|
|
1256
|
+
}
|
|
1257
|
+
: { metadata, ...heatmap === null || heatmap === void 0 ? void 0 : heatmap.content };
|
|
1252
1258
|
queueEventForBatchedSending(coframe, data);
|
|
1253
1259
|
}
|
|
1254
1260
|
function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken, experimentId, variantId, }) {
|
|
@@ -1263,7 +1269,7 @@ function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken
|
|
|
1263
1269
|
user_token: userToken,
|
|
1264
1270
|
});
|
|
1265
1271
|
}
|
|
1266
|
-
function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, duration = 0, userToken, personalizationHeaders, }) {
|
|
1272
|
+
function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, orgId, duration = 0, userToken, personalizationHeaders, collect, }) {
|
|
1267
1273
|
var _a;
|
|
1268
1274
|
if (event
|
|
1269
1275
|
.composedPath()
|
|
@@ -1286,6 +1292,7 @@ function sendPageEngagementEvent(coframe, eventType, event, { projectId, session
|
|
|
1286
1292
|
session_id: sessionId,
|
|
1287
1293
|
time: new Date(),
|
|
1288
1294
|
url: getCurrentPageUrl(),
|
|
1295
|
+
org_id: orgId,
|
|
1289
1296
|
user_token: userToken,
|
|
1290
1297
|
content: {
|
|
1291
1298
|
universal_selector: getSelector(targetElement, {
|
|
@@ -1308,7 +1315,10 @@ function sendPageEngagementEvent(coframe, eventType, event, { projectId, session
|
|
|
1308
1315
|
}),
|
|
1309
1316
|
},
|
|
1310
1317
|
};
|
|
1311
|
-
|
|
1318
|
+
const isConversion = Boolean(metricIds === null || metricIds === void 0 ? void 0 : metricIds.length);
|
|
1319
|
+
if (!(collect === null || collect === void 0 ? void 0 : collect(data, realEventTarget, event, isConversion))) {
|
|
1320
|
+
queueEventForBatchedSending(coframe, data, isConversion);
|
|
1321
|
+
}
|
|
1312
1322
|
const processingDuration = performance.now() - startTime;
|
|
1313
1323
|
if (coframe.status) {
|
|
1314
1324
|
if (!coframe.status.events) {
|
|
@@ -3382,6 +3392,235 @@ function notifyEventsFlushed() {
|
|
|
3382
3392
|
}
|
|
3383
3393
|
}
|
|
3384
3394
|
|
|
3395
|
+
const DEFAULT_BLOCK_SELECTOR = '[data-cf-block],.cf-block';
|
|
3396
|
+
const INTERACTIVE_SELECTOR = 'a,button,input,select,textarea,label,summary,[href],[onclick],[contenteditable],[tabindex]:not([tabindex="-1"]),[role=button],[role=link],[role=tab],[role=checkbox],[role=menuitem]';
|
|
3397
|
+
const HOLD_MS = 1000;
|
|
3398
|
+
const RAGE_WINDOW_MS = 700;
|
|
3399
|
+
const RAGE_RADIUS_PX = 30;
|
|
3400
|
+
const RAGE_CLICKS = 3;
|
|
3401
|
+
let enabled = false;
|
|
3402
|
+
let allPages = false;
|
|
3403
|
+
let coframe = null;
|
|
3404
|
+
let blockSelector = DEFAULT_BLOCK_SELECTOR;
|
|
3405
|
+
const held = [];
|
|
3406
|
+
let recent = [];
|
|
3407
|
+
let lastActivity = 0;
|
|
3408
|
+
let observer = null;
|
|
3409
|
+
let pageView = '';
|
|
3410
|
+
let maxDepth = 0;
|
|
3411
|
+
let engagedMs = 0;
|
|
3412
|
+
let visibleSince = null;
|
|
3413
|
+
let navigated = false;
|
|
3414
|
+
function meta(name) {
|
|
3415
|
+
const tag = document.querySelector(`meta[name="coframe:${name}"]`);
|
|
3416
|
+
return (tag === null || tag === void 0 ? void 0 : tag.getAttribute('content')) || undefined;
|
|
3417
|
+
}
|
|
3418
|
+
function heatmapActive() {
|
|
3419
|
+
return enabled && (allPages || !!meta('page'));
|
|
3420
|
+
}
|
|
3421
|
+
function pageFields(withHeight) {
|
|
3422
|
+
const fields = {
|
|
3423
|
+
page: meta('page'),
|
|
3424
|
+
ver: meta('version'),
|
|
3425
|
+
variant: meta('variant'),
|
|
3426
|
+
row: meta('row'),
|
|
3427
|
+
};
|
|
3428
|
+
if (withHeight)
|
|
3429
|
+
fields.doc_h = document.documentElement.scrollHeight;
|
|
3430
|
+
return fields;
|
|
3431
|
+
}
|
|
3432
|
+
function round3(value) {
|
|
3433
|
+
return Math.round(Math.min(1, Math.max(0, value)) * 1000) / 1000;
|
|
3434
|
+
}
|
|
3435
|
+
function markActivity() {
|
|
3436
|
+
lastActivity = Date.now();
|
|
3437
|
+
}
|
|
3438
|
+
function viewportBottom() {
|
|
3439
|
+
return Math.round(window.scrollY + window.innerHeight);
|
|
3440
|
+
}
|
|
3441
|
+
function restartCounters(depth) {
|
|
3442
|
+
maxDepth = depth;
|
|
3443
|
+
engagedMs = 0;
|
|
3444
|
+
visibleSince = document.hidden ? null : Date.now();
|
|
3445
|
+
}
|
|
3446
|
+
function syncPageView() {
|
|
3447
|
+
if (!coframe || coframe.sessionId === pageView)
|
|
3448
|
+
return;
|
|
3449
|
+
pageView = coframe.sessionId;
|
|
3450
|
+
if (navigated)
|
|
3451
|
+
navigated = false;
|
|
3452
|
+
else
|
|
3453
|
+
restartCounters(viewportBottom());
|
|
3454
|
+
}
|
|
3455
|
+
function onScroll() {
|
|
3456
|
+
markActivity();
|
|
3457
|
+
syncPageView();
|
|
3458
|
+
maxDepth = Math.max(maxDepth, viewportBottom());
|
|
3459
|
+
}
|
|
3460
|
+
function onVisibility() {
|
|
3461
|
+
if (document.hidden) {
|
|
3462
|
+
if (visibleSince !== null)
|
|
3463
|
+
engagedMs += Date.now() - visibleSince;
|
|
3464
|
+
visibleSince = null;
|
|
3465
|
+
releaseHeldClicks();
|
|
3466
|
+
}
|
|
3467
|
+
else if (visibleSince === null) {
|
|
3468
|
+
visibleSince = Date.now();
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
function readBlockSelector(selector) {
|
|
3472
|
+
if (typeof selector !== 'string' || !selector)
|
|
3473
|
+
return DEFAULT_BLOCK_SELECTOR;
|
|
3474
|
+
try {
|
|
3475
|
+
document.createElement('div').matches(selector);
|
|
3476
|
+
return selector;
|
|
3477
|
+
}
|
|
3478
|
+
catch (_a) {
|
|
3479
|
+
return DEFAULT_BLOCK_SELECTOR;
|
|
3480
|
+
}
|
|
3481
|
+
}
|
|
3482
|
+
function startHeatmaps(target, project) {
|
|
3483
|
+
var _a, _b;
|
|
3484
|
+
const settings = (_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.heatmaps;
|
|
3485
|
+
if (enabled || !(settings === null || settings === void 0 ? void 0 : settings.enabled))
|
|
3486
|
+
return;
|
|
3487
|
+
enabled = true;
|
|
3488
|
+
allPages = !!settings.all_pages;
|
|
3489
|
+
blockSelector = readBlockSelector((_b = project.settings.session_replay) === null || _b === void 0 ? void 0 : _b.block_selector);
|
|
3490
|
+
coframe = target;
|
|
3491
|
+
syncPageView();
|
|
3492
|
+
document.addEventListener('scroll', onScroll, {
|
|
3493
|
+
capture: true,
|
|
3494
|
+
passive: true,
|
|
3495
|
+
});
|
|
3496
|
+
document.addEventListener('visibilitychange', onVisibility);
|
|
3497
|
+
window.addEventListener('pagehide', releaseHeldClicks);
|
|
3498
|
+
window.addEventListener('beforeunload', releaseHeldClicks);
|
|
3499
|
+
}
|
|
3500
|
+
function leaveFields() {
|
|
3501
|
+
if (!heatmapActive())
|
|
3502
|
+
return undefined;
|
|
3503
|
+
syncPageView();
|
|
3504
|
+
if (navigated)
|
|
3505
|
+
return undefined;
|
|
3506
|
+
return {
|
|
3507
|
+
content: {
|
|
3508
|
+
scroll_depth: Math.max(maxDepth, viewportBottom()),
|
|
3509
|
+
'duration-ms': Math.round(engagedMs + (visibleSince === null ? 0 : Date.now() - visibleSince)),
|
|
3510
|
+
},
|
|
3511
|
+
hm: pageFields(true),
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3514
|
+
function pageLeaveFields() {
|
|
3515
|
+
if (!enabled)
|
|
3516
|
+
return undefined;
|
|
3517
|
+
const fields = leaveFields();
|
|
3518
|
+
restartCounters(0);
|
|
3519
|
+
navigated = true;
|
|
3520
|
+
return fields;
|
|
3521
|
+
}
|
|
3522
|
+
function watchMutations() {
|
|
3523
|
+
if (observer || typeof MutationObserver !== 'function')
|
|
3524
|
+
return;
|
|
3525
|
+
observer = new MutationObserver(markActivity);
|
|
3526
|
+
observer.observe(document.documentElement, {
|
|
3527
|
+
attributes: true,
|
|
3528
|
+
characterData: true,
|
|
3529
|
+
childList: true,
|
|
3530
|
+
subtree: true,
|
|
3531
|
+
});
|
|
3532
|
+
}
|
|
3533
|
+
function settle(click) {
|
|
3534
|
+
const index = held.indexOf(click);
|
|
3535
|
+
if (index < 0)
|
|
3536
|
+
return;
|
|
3537
|
+
held.splice(index, 1);
|
|
3538
|
+
if (click.hm.kind !== 'rage') {
|
|
3539
|
+
const dead = click.candidate &&
|
|
3540
|
+
lastActivity < click.t &&
|
|
3541
|
+
document.activeElement === click.focused &&
|
|
3542
|
+
location.href === click.href;
|
|
3543
|
+
click.hm.kind = dead ? 'dead' : 'click';
|
|
3544
|
+
}
|
|
3545
|
+
if (coframe)
|
|
3546
|
+
queueEventForBatchedSending(coframe, click.data);
|
|
3547
|
+
if (observer && !held.some((h) => h.candidate)) {
|
|
3548
|
+
observer.disconnect();
|
|
3549
|
+
observer = null;
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
function releaseHeldClicks() {
|
|
3553
|
+
for (const click of held.splice(0)) {
|
|
3554
|
+
if (click.hm.kind === undefined)
|
|
3555
|
+
click.hm.kind = null;
|
|
3556
|
+
if (coframe)
|
|
3557
|
+
queueEventForBatchedSending(coframe, click.data);
|
|
3558
|
+
}
|
|
3559
|
+
if (observer) {
|
|
3560
|
+
observer.disconnect();
|
|
3561
|
+
observer = null;
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
function copyKey(node, id) {
|
|
3565
|
+
const items = [];
|
|
3566
|
+
for (let at = node; at; at = at.parentElement) {
|
|
3567
|
+
const item = at.getAttribute('data-el-item');
|
|
3568
|
+
if (item)
|
|
3569
|
+
items.unshift(item);
|
|
3570
|
+
}
|
|
3571
|
+
return items.length ? `${id}~${items.join('.')}` : id;
|
|
3572
|
+
}
|
|
3573
|
+
function collectClick(data, target, event, isConversion) {
|
|
3574
|
+
if (!target.closest || target.closest(blockSelector))
|
|
3575
|
+
return false;
|
|
3576
|
+
const content = data.content;
|
|
3577
|
+
const position = content.position;
|
|
3578
|
+
const hm = pageFields(true);
|
|
3579
|
+
const anchor = target.closest('[data-el]');
|
|
3580
|
+
if (anchor) {
|
|
3581
|
+
const id = anchor.getAttribute('data-el');
|
|
3582
|
+
hm.el = id ? copyKey(anchor, id) : undefined;
|
|
3583
|
+
const rect = anchor.getBoundingClientRect();
|
|
3584
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
3585
|
+
hm.fx = round3((event.clientX - rect.left) / rect.width);
|
|
3586
|
+
hm.fy = round3((event.clientY - rect.top) / rect.height);
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
content.metadata = {
|
|
3590
|
+
...content.metadata,
|
|
3591
|
+
hm,
|
|
3592
|
+
};
|
|
3593
|
+
const now = Date.now();
|
|
3594
|
+
const click = {
|
|
3595
|
+
data,
|
|
3596
|
+
hm,
|
|
3597
|
+
x: position.x,
|
|
3598
|
+
y: position.y,
|
|
3599
|
+
t: now,
|
|
3600
|
+
candidate: !target.closest(INTERACTIVE_SELECTOR),
|
|
3601
|
+
focused: document.activeElement,
|
|
3602
|
+
href: location.href,
|
|
3603
|
+
};
|
|
3604
|
+
recent = recent.filter((r) => now - r.t <= RAGE_WINDOW_MS);
|
|
3605
|
+
recent.push(click);
|
|
3606
|
+
const cluster = recent.filter((r) => Math.abs(r.x - click.x) <= RAGE_RADIUS_PX &&
|
|
3607
|
+
Math.abs(r.y - click.y) <= RAGE_RADIUS_PX);
|
|
3608
|
+
if (cluster.length >= RAGE_CLICKS) {
|
|
3609
|
+
for (const r of cluster)
|
|
3610
|
+
r.hm.kind = 'rage';
|
|
3611
|
+
}
|
|
3612
|
+
if (isConversion) {
|
|
3613
|
+
if (hm.kind === undefined)
|
|
3614
|
+
hm.kind = null;
|
|
3615
|
+
return false;
|
|
3616
|
+
}
|
|
3617
|
+
held.push(click);
|
|
3618
|
+
if (click.candidate)
|
|
3619
|
+
watchMutations();
|
|
3620
|
+
setTimeout(() => settle(click), HOLD_MS);
|
|
3621
|
+
return true;
|
|
3622
|
+
}
|
|
3623
|
+
|
|
3385
3624
|
function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders, sessionContext, pageUrl = getCurrentPageUrl()) {
|
|
3386
3625
|
const sessionPayload = [
|
|
3387
3626
|
Coframe,
|
|
@@ -3408,7 +3647,7 @@ function startSession(Coframe, cookiesEnabled, executionStartTime, personalizati
|
|
|
3408
3647
|
orgId: Coframe.orgId,
|
|
3409
3648
|
userToken: Coframe.userToken,
|
|
3410
3649
|
personalizationHeaders,
|
|
3411
|
-
});
|
|
3650
|
+
}, heatmapActive() ? { hm: pageFields(false) } : undefined);
|
|
3412
3651
|
}
|
|
3413
3652
|
function reportInitTiming(Coframe, project, integrationStartTime, executionStartTime) {
|
|
3414
3653
|
var _a;
|
|
@@ -3641,20 +3880,15 @@ function setupListeners(Coframe, executionStartTime) {
|
|
|
3641
3880
|
sendPageEngagementEvent(Coframe, 'click', event, {
|
|
3642
3881
|
projectId: Coframe.projectId,
|
|
3643
3882
|
sessionId: Coframe.sessionId,
|
|
3883
|
+
orgId: Coframe.orgId,
|
|
3644
3884
|
userToken: Coframe.userToken,
|
|
3645
3885
|
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3886
|
+
collect: heatmapActive() ? collectClick : undefined,
|
|
3646
3887
|
});
|
|
3647
3888
|
};
|
|
3648
3889
|
document.addEventListener('click', handleClick, true);
|
|
3649
3890
|
const handleEventFlush = debounce((eventType) => {
|
|
3650
|
-
|
|
3651
|
-
projectId: Coframe.projectId,
|
|
3652
|
-
sessionId: Coframe.sessionId,
|
|
3653
|
-
eventType: eventType,
|
|
3654
|
-
orgId: Coframe.orgId,
|
|
3655
|
-
userToken: Coframe.userToken,
|
|
3656
|
-
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3657
|
-
});
|
|
3891
|
+
queueLeaveEvent(Coframe, eventType, eventType === 'tab_show' ? undefined : leaveFields());
|
|
3658
3892
|
flushQueuedEvents(Coframe.projectId);
|
|
3659
3893
|
notifyEventsFlushed();
|
|
3660
3894
|
}, 1);
|
|
@@ -3666,11 +3900,27 @@ function setupListeners(Coframe, executionStartTime) {
|
|
|
3666
3900
|
handleEventFlush(eventType);
|
|
3667
3901
|
});
|
|
3668
3902
|
}
|
|
3903
|
+
function queueLeaveEvent(Coframe, eventType, fields) {
|
|
3904
|
+
queueEvent(Coframe, {
|
|
3905
|
+
projectId: Coframe.projectId,
|
|
3906
|
+
sessionId: Coframe.sessionId,
|
|
3907
|
+
eventType,
|
|
3908
|
+
orgId: Coframe.orgId,
|
|
3909
|
+
userToken: Coframe.userToken,
|
|
3910
|
+
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3911
|
+
}, fields);
|
|
3912
|
+
}
|
|
3913
|
+
function sendPageLeave(Coframe) {
|
|
3914
|
+
const fields = pageLeaveFields();
|
|
3915
|
+
if (fields)
|
|
3916
|
+
queueLeaveEvent(Coframe, 'page_leave', fields);
|
|
3917
|
+
}
|
|
3669
3918
|
function setupTracking(Coframe, projectResult, previewVariantId, executionStartTime, nonce, waitForCookiesEnabled, onConsentChange) {
|
|
3670
3919
|
var _a, _b;
|
|
3671
3920
|
const logger = Coframe.logger;
|
|
3672
3921
|
const { project } = projectResult;
|
|
3673
3922
|
setTrackOnlyActivatedFrames(!!((_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.track_only_activated_frames));
|
|
3923
|
+
startHeatmaps(Coframe, project);
|
|
3674
3924
|
const analytics = createTreatmentAnalytics(Coframe, previewVariantId);
|
|
3675
3925
|
setupListeners(Coframe, executionStartTime);
|
|
3676
3926
|
const managedAnalyticsCallback = (_b = project === null || project === void 0 ? void 0 : project.settings) === null || _b === void 0 ? void 0 : _b.analytics_callback;
|
|
@@ -3786,6 +4036,7 @@ function setupSPANavigation(Coframe, project, config, previewVariantId, isSessio
|
|
|
3786
4036
|
let navigationAbortController = null;
|
|
3787
4037
|
observeUrlChanges(false, async (newPageUrl, _oldPageUrl) => {
|
|
3788
4038
|
var _a;
|
|
4039
|
+
sendPageLeave(Coframe);
|
|
3789
4040
|
if (navigationAbortController)
|
|
3790
4041
|
navigationAbortController.abort();
|
|
3791
4042
|
navigationAbortController = new AbortController();
|
package/dist/pkg/cf.esm.mjs
CHANGED
|
@@ -1123,7 +1123,7 @@ function warnEventsNotSent() {
|
|
|
1123
1123
|
}
|
|
1124
1124
|
}
|
|
1125
1125
|
|
|
1126
|
-
const SDK_VERSION = '2.
|
|
1126
|
+
const SDK_VERSION = '2.9.0';
|
|
1127
1127
|
const queuedEvents = [];
|
|
1128
1128
|
const queuedMonitoringEvents = [];
|
|
1129
1129
|
const queuedSessions = [];
|
|
@@ -1228,7 +1228,7 @@ function flushQueuedEvents(projectId) {
|
|
|
1228
1228
|
queuedSessions.length = 0;
|
|
1229
1229
|
}
|
|
1230
1230
|
}
|
|
1231
|
-
function queueEvent(coframe, sessionInfo) {
|
|
1231
|
+
function queueEvent(coframe, sessionInfo, heatmap) {
|
|
1232
1232
|
const { projectId, sessionId, eventType, orgId, userToken } = sessionInfo;
|
|
1233
1233
|
const data = {
|
|
1234
1234
|
type: eventType,
|
|
@@ -1240,13 +1240,19 @@ function queueEvent(coframe, sessionInfo) {
|
|
|
1240
1240
|
user_token: userToken,
|
|
1241
1241
|
};
|
|
1242
1242
|
const seg = sessionInfo.personalizationHeaders;
|
|
1243
|
-
const metadata = seg
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1243
|
+
const metadata = seg
|
|
1244
|
+
? { personalization_headers: { ...seg } }
|
|
1245
|
+
: {};
|
|
1246
|
+
if (heatmap === null || heatmap === void 0 ? void 0 : heatmap.hm)
|
|
1247
|
+
metadata.hm = heatmap.hm;
|
|
1248
|
+
data.content =
|
|
1249
|
+
eventType === 'page_view'
|
|
1250
|
+
? {
|
|
1251
|
+
universal_selector: {},
|
|
1252
|
+
metadata,
|
|
1253
|
+
screen_size: { width: window.innerWidth, height: window.innerHeight },
|
|
1254
|
+
}
|
|
1255
|
+
: { metadata, ...heatmap === null || heatmap === void 0 ? void 0 : heatmap.content };
|
|
1250
1256
|
queueEventForBatchedSending(coframe, data);
|
|
1251
1257
|
}
|
|
1252
1258
|
function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken, experimentId, variantId, }) {
|
|
@@ -1261,7 +1267,7 @@ function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken
|
|
|
1261
1267
|
user_token: userToken,
|
|
1262
1268
|
});
|
|
1263
1269
|
}
|
|
1264
|
-
function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, duration = 0, userToken, personalizationHeaders, }) {
|
|
1270
|
+
function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, orgId, duration = 0, userToken, personalizationHeaders, collect, }) {
|
|
1265
1271
|
var _a;
|
|
1266
1272
|
if (event
|
|
1267
1273
|
.composedPath()
|
|
@@ -1284,6 +1290,7 @@ function sendPageEngagementEvent(coframe, eventType, event, { projectId, session
|
|
|
1284
1290
|
session_id: sessionId,
|
|
1285
1291
|
time: new Date(),
|
|
1286
1292
|
url: getCurrentPageUrl(),
|
|
1293
|
+
org_id: orgId,
|
|
1287
1294
|
user_token: userToken,
|
|
1288
1295
|
content: {
|
|
1289
1296
|
universal_selector: getSelector(targetElement, {
|
|
@@ -1306,7 +1313,10 @@ function sendPageEngagementEvent(coframe, eventType, event, { projectId, session
|
|
|
1306
1313
|
}),
|
|
1307
1314
|
},
|
|
1308
1315
|
};
|
|
1309
|
-
|
|
1316
|
+
const isConversion = Boolean(metricIds === null || metricIds === void 0 ? void 0 : metricIds.length);
|
|
1317
|
+
if (!(collect === null || collect === void 0 ? void 0 : collect(data, realEventTarget, event, isConversion))) {
|
|
1318
|
+
queueEventForBatchedSending(coframe, data, isConversion);
|
|
1319
|
+
}
|
|
1310
1320
|
const processingDuration = performance.now() - startTime;
|
|
1311
1321
|
if (coframe.status) {
|
|
1312
1322
|
if (!coframe.status.events) {
|
|
@@ -3380,6 +3390,235 @@ function notifyEventsFlushed() {
|
|
|
3380
3390
|
}
|
|
3381
3391
|
}
|
|
3382
3392
|
|
|
3393
|
+
const DEFAULT_BLOCK_SELECTOR = '[data-cf-block],.cf-block';
|
|
3394
|
+
const INTERACTIVE_SELECTOR = 'a,button,input,select,textarea,label,summary,[href],[onclick],[contenteditable],[tabindex]:not([tabindex="-1"]),[role=button],[role=link],[role=tab],[role=checkbox],[role=menuitem]';
|
|
3395
|
+
const HOLD_MS = 1000;
|
|
3396
|
+
const RAGE_WINDOW_MS = 700;
|
|
3397
|
+
const RAGE_RADIUS_PX = 30;
|
|
3398
|
+
const RAGE_CLICKS = 3;
|
|
3399
|
+
let enabled = false;
|
|
3400
|
+
let allPages = false;
|
|
3401
|
+
let coframe = null;
|
|
3402
|
+
let blockSelector = DEFAULT_BLOCK_SELECTOR;
|
|
3403
|
+
const held = [];
|
|
3404
|
+
let recent = [];
|
|
3405
|
+
let lastActivity = 0;
|
|
3406
|
+
let observer = null;
|
|
3407
|
+
let pageView = '';
|
|
3408
|
+
let maxDepth = 0;
|
|
3409
|
+
let engagedMs = 0;
|
|
3410
|
+
let visibleSince = null;
|
|
3411
|
+
let navigated = false;
|
|
3412
|
+
function meta(name) {
|
|
3413
|
+
const tag = document.querySelector(`meta[name="coframe:${name}"]`);
|
|
3414
|
+
return (tag === null || tag === void 0 ? void 0 : tag.getAttribute('content')) || undefined;
|
|
3415
|
+
}
|
|
3416
|
+
function heatmapActive() {
|
|
3417
|
+
return enabled && (allPages || !!meta('page'));
|
|
3418
|
+
}
|
|
3419
|
+
function pageFields(withHeight) {
|
|
3420
|
+
const fields = {
|
|
3421
|
+
page: meta('page'),
|
|
3422
|
+
ver: meta('version'),
|
|
3423
|
+
variant: meta('variant'),
|
|
3424
|
+
row: meta('row'),
|
|
3425
|
+
};
|
|
3426
|
+
if (withHeight)
|
|
3427
|
+
fields.doc_h = document.documentElement.scrollHeight;
|
|
3428
|
+
return fields;
|
|
3429
|
+
}
|
|
3430
|
+
function round3(value) {
|
|
3431
|
+
return Math.round(Math.min(1, Math.max(0, value)) * 1000) / 1000;
|
|
3432
|
+
}
|
|
3433
|
+
function markActivity() {
|
|
3434
|
+
lastActivity = Date.now();
|
|
3435
|
+
}
|
|
3436
|
+
function viewportBottom() {
|
|
3437
|
+
return Math.round(window.scrollY + window.innerHeight);
|
|
3438
|
+
}
|
|
3439
|
+
function restartCounters(depth) {
|
|
3440
|
+
maxDepth = depth;
|
|
3441
|
+
engagedMs = 0;
|
|
3442
|
+
visibleSince = document.hidden ? null : Date.now();
|
|
3443
|
+
}
|
|
3444
|
+
function syncPageView() {
|
|
3445
|
+
if (!coframe || coframe.sessionId === pageView)
|
|
3446
|
+
return;
|
|
3447
|
+
pageView = coframe.sessionId;
|
|
3448
|
+
if (navigated)
|
|
3449
|
+
navigated = false;
|
|
3450
|
+
else
|
|
3451
|
+
restartCounters(viewportBottom());
|
|
3452
|
+
}
|
|
3453
|
+
function onScroll() {
|
|
3454
|
+
markActivity();
|
|
3455
|
+
syncPageView();
|
|
3456
|
+
maxDepth = Math.max(maxDepth, viewportBottom());
|
|
3457
|
+
}
|
|
3458
|
+
function onVisibility() {
|
|
3459
|
+
if (document.hidden) {
|
|
3460
|
+
if (visibleSince !== null)
|
|
3461
|
+
engagedMs += Date.now() - visibleSince;
|
|
3462
|
+
visibleSince = null;
|
|
3463
|
+
releaseHeldClicks();
|
|
3464
|
+
}
|
|
3465
|
+
else if (visibleSince === null) {
|
|
3466
|
+
visibleSince = Date.now();
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3469
|
+
function readBlockSelector(selector) {
|
|
3470
|
+
if (typeof selector !== 'string' || !selector)
|
|
3471
|
+
return DEFAULT_BLOCK_SELECTOR;
|
|
3472
|
+
try {
|
|
3473
|
+
document.createElement('div').matches(selector);
|
|
3474
|
+
return selector;
|
|
3475
|
+
}
|
|
3476
|
+
catch (_a) {
|
|
3477
|
+
return DEFAULT_BLOCK_SELECTOR;
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
function startHeatmaps(target, project) {
|
|
3481
|
+
var _a, _b;
|
|
3482
|
+
const settings = (_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.heatmaps;
|
|
3483
|
+
if (enabled || !(settings === null || settings === void 0 ? void 0 : settings.enabled))
|
|
3484
|
+
return;
|
|
3485
|
+
enabled = true;
|
|
3486
|
+
allPages = !!settings.all_pages;
|
|
3487
|
+
blockSelector = readBlockSelector((_b = project.settings.session_replay) === null || _b === void 0 ? void 0 : _b.block_selector);
|
|
3488
|
+
coframe = target;
|
|
3489
|
+
syncPageView();
|
|
3490
|
+
document.addEventListener('scroll', onScroll, {
|
|
3491
|
+
capture: true,
|
|
3492
|
+
passive: true,
|
|
3493
|
+
});
|
|
3494
|
+
document.addEventListener('visibilitychange', onVisibility);
|
|
3495
|
+
window.addEventListener('pagehide', releaseHeldClicks);
|
|
3496
|
+
window.addEventListener('beforeunload', releaseHeldClicks);
|
|
3497
|
+
}
|
|
3498
|
+
function leaveFields() {
|
|
3499
|
+
if (!heatmapActive())
|
|
3500
|
+
return undefined;
|
|
3501
|
+
syncPageView();
|
|
3502
|
+
if (navigated)
|
|
3503
|
+
return undefined;
|
|
3504
|
+
return {
|
|
3505
|
+
content: {
|
|
3506
|
+
scroll_depth: Math.max(maxDepth, viewportBottom()),
|
|
3507
|
+
'duration-ms': Math.round(engagedMs + (visibleSince === null ? 0 : Date.now() - visibleSince)),
|
|
3508
|
+
},
|
|
3509
|
+
hm: pageFields(true),
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3512
|
+
function pageLeaveFields() {
|
|
3513
|
+
if (!enabled)
|
|
3514
|
+
return undefined;
|
|
3515
|
+
const fields = leaveFields();
|
|
3516
|
+
restartCounters(0);
|
|
3517
|
+
navigated = true;
|
|
3518
|
+
return fields;
|
|
3519
|
+
}
|
|
3520
|
+
function watchMutations() {
|
|
3521
|
+
if (observer || typeof MutationObserver !== 'function')
|
|
3522
|
+
return;
|
|
3523
|
+
observer = new MutationObserver(markActivity);
|
|
3524
|
+
observer.observe(document.documentElement, {
|
|
3525
|
+
attributes: true,
|
|
3526
|
+
characterData: true,
|
|
3527
|
+
childList: true,
|
|
3528
|
+
subtree: true,
|
|
3529
|
+
});
|
|
3530
|
+
}
|
|
3531
|
+
function settle(click) {
|
|
3532
|
+
const index = held.indexOf(click);
|
|
3533
|
+
if (index < 0)
|
|
3534
|
+
return;
|
|
3535
|
+
held.splice(index, 1);
|
|
3536
|
+
if (click.hm.kind !== 'rage') {
|
|
3537
|
+
const dead = click.candidate &&
|
|
3538
|
+
lastActivity < click.t &&
|
|
3539
|
+
document.activeElement === click.focused &&
|
|
3540
|
+
location.href === click.href;
|
|
3541
|
+
click.hm.kind = dead ? 'dead' : 'click';
|
|
3542
|
+
}
|
|
3543
|
+
if (coframe)
|
|
3544
|
+
queueEventForBatchedSending(coframe, click.data);
|
|
3545
|
+
if (observer && !held.some((h) => h.candidate)) {
|
|
3546
|
+
observer.disconnect();
|
|
3547
|
+
observer = null;
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
function releaseHeldClicks() {
|
|
3551
|
+
for (const click of held.splice(0)) {
|
|
3552
|
+
if (click.hm.kind === undefined)
|
|
3553
|
+
click.hm.kind = null;
|
|
3554
|
+
if (coframe)
|
|
3555
|
+
queueEventForBatchedSending(coframe, click.data);
|
|
3556
|
+
}
|
|
3557
|
+
if (observer) {
|
|
3558
|
+
observer.disconnect();
|
|
3559
|
+
observer = null;
|
|
3560
|
+
}
|
|
3561
|
+
}
|
|
3562
|
+
function copyKey(node, id) {
|
|
3563
|
+
const items = [];
|
|
3564
|
+
for (let at = node; at; at = at.parentElement) {
|
|
3565
|
+
const item = at.getAttribute('data-el-item');
|
|
3566
|
+
if (item)
|
|
3567
|
+
items.unshift(item);
|
|
3568
|
+
}
|
|
3569
|
+
return items.length ? `${id}~${items.join('.')}` : id;
|
|
3570
|
+
}
|
|
3571
|
+
function collectClick(data, target, event, isConversion) {
|
|
3572
|
+
if (!target.closest || target.closest(blockSelector))
|
|
3573
|
+
return false;
|
|
3574
|
+
const content = data.content;
|
|
3575
|
+
const position = content.position;
|
|
3576
|
+
const hm = pageFields(true);
|
|
3577
|
+
const anchor = target.closest('[data-el]');
|
|
3578
|
+
if (anchor) {
|
|
3579
|
+
const id = anchor.getAttribute('data-el');
|
|
3580
|
+
hm.el = id ? copyKey(anchor, id) : undefined;
|
|
3581
|
+
const rect = anchor.getBoundingClientRect();
|
|
3582
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
3583
|
+
hm.fx = round3((event.clientX - rect.left) / rect.width);
|
|
3584
|
+
hm.fy = round3((event.clientY - rect.top) / rect.height);
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
content.metadata = {
|
|
3588
|
+
...content.metadata,
|
|
3589
|
+
hm,
|
|
3590
|
+
};
|
|
3591
|
+
const now = Date.now();
|
|
3592
|
+
const click = {
|
|
3593
|
+
data,
|
|
3594
|
+
hm,
|
|
3595
|
+
x: position.x,
|
|
3596
|
+
y: position.y,
|
|
3597
|
+
t: now,
|
|
3598
|
+
candidate: !target.closest(INTERACTIVE_SELECTOR),
|
|
3599
|
+
focused: document.activeElement,
|
|
3600
|
+
href: location.href,
|
|
3601
|
+
};
|
|
3602
|
+
recent = recent.filter((r) => now - r.t <= RAGE_WINDOW_MS);
|
|
3603
|
+
recent.push(click);
|
|
3604
|
+
const cluster = recent.filter((r) => Math.abs(r.x - click.x) <= RAGE_RADIUS_PX &&
|
|
3605
|
+
Math.abs(r.y - click.y) <= RAGE_RADIUS_PX);
|
|
3606
|
+
if (cluster.length >= RAGE_CLICKS) {
|
|
3607
|
+
for (const r of cluster)
|
|
3608
|
+
r.hm.kind = 'rage';
|
|
3609
|
+
}
|
|
3610
|
+
if (isConversion) {
|
|
3611
|
+
if (hm.kind === undefined)
|
|
3612
|
+
hm.kind = null;
|
|
3613
|
+
return false;
|
|
3614
|
+
}
|
|
3615
|
+
held.push(click);
|
|
3616
|
+
if (click.candidate)
|
|
3617
|
+
watchMutations();
|
|
3618
|
+
setTimeout(() => settle(click), HOLD_MS);
|
|
3619
|
+
return true;
|
|
3620
|
+
}
|
|
3621
|
+
|
|
3383
3622
|
function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders, sessionContext, pageUrl = getCurrentPageUrl()) {
|
|
3384
3623
|
const sessionPayload = [
|
|
3385
3624
|
Coframe,
|
|
@@ -3406,7 +3645,7 @@ function startSession(Coframe, cookiesEnabled, executionStartTime, personalizati
|
|
|
3406
3645
|
orgId: Coframe.orgId,
|
|
3407
3646
|
userToken: Coframe.userToken,
|
|
3408
3647
|
personalizationHeaders,
|
|
3409
|
-
});
|
|
3648
|
+
}, heatmapActive() ? { hm: pageFields(false) } : undefined);
|
|
3410
3649
|
}
|
|
3411
3650
|
function reportInitTiming(Coframe, project, integrationStartTime, executionStartTime) {
|
|
3412
3651
|
var _a;
|
|
@@ -3639,20 +3878,15 @@ function setupListeners(Coframe, executionStartTime) {
|
|
|
3639
3878
|
sendPageEngagementEvent(Coframe, 'click', event, {
|
|
3640
3879
|
projectId: Coframe.projectId,
|
|
3641
3880
|
sessionId: Coframe.sessionId,
|
|
3881
|
+
orgId: Coframe.orgId,
|
|
3642
3882
|
userToken: Coframe.userToken,
|
|
3643
3883
|
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3884
|
+
collect: heatmapActive() ? collectClick : undefined,
|
|
3644
3885
|
});
|
|
3645
3886
|
};
|
|
3646
3887
|
document.addEventListener('click', handleClick, true);
|
|
3647
3888
|
const handleEventFlush = debounce((eventType) => {
|
|
3648
|
-
|
|
3649
|
-
projectId: Coframe.projectId,
|
|
3650
|
-
sessionId: Coframe.sessionId,
|
|
3651
|
-
eventType: eventType,
|
|
3652
|
-
orgId: Coframe.orgId,
|
|
3653
|
-
userToken: Coframe.userToken,
|
|
3654
|
-
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3655
|
-
});
|
|
3889
|
+
queueLeaveEvent(Coframe, eventType, eventType === 'tab_show' ? undefined : leaveFields());
|
|
3656
3890
|
flushQueuedEvents(Coframe.projectId);
|
|
3657
3891
|
notifyEventsFlushed();
|
|
3658
3892
|
}, 1);
|
|
@@ -3664,11 +3898,27 @@ function setupListeners(Coframe, executionStartTime) {
|
|
|
3664
3898
|
handleEventFlush(eventType);
|
|
3665
3899
|
});
|
|
3666
3900
|
}
|
|
3901
|
+
function queueLeaveEvent(Coframe, eventType, fields) {
|
|
3902
|
+
queueEvent(Coframe, {
|
|
3903
|
+
projectId: Coframe.projectId,
|
|
3904
|
+
sessionId: Coframe.sessionId,
|
|
3905
|
+
eventType,
|
|
3906
|
+
orgId: Coframe.orgId,
|
|
3907
|
+
userToken: Coframe.userToken,
|
|
3908
|
+
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3909
|
+
}, fields);
|
|
3910
|
+
}
|
|
3911
|
+
function sendPageLeave(Coframe) {
|
|
3912
|
+
const fields = pageLeaveFields();
|
|
3913
|
+
if (fields)
|
|
3914
|
+
queueLeaveEvent(Coframe, 'page_leave', fields);
|
|
3915
|
+
}
|
|
3667
3916
|
function setupTracking(Coframe, projectResult, previewVariantId, executionStartTime, nonce, waitForCookiesEnabled, onConsentChange) {
|
|
3668
3917
|
var _a, _b;
|
|
3669
3918
|
const logger = Coframe.logger;
|
|
3670
3919
|
const { project } = projectResult;
|
|
3671
3920
|
setTrackOnlyActivatedFrames(!!((_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.track_only_activated_frames));
|
|
3921
|
+
startHeatmaps(Coframe, project);
|
|
3672
3922
|
const analytics = createTreatmentAnalytics(Coframe, previewVariantId);
|
|
3673
3923
|
setupListeners(Coframe, executionStartTime);
|
|
3674
3924
|
const managedAnalyticsCallback = (_b = project === null || project === void 0 ? void 0 : project.settings) === null || _b === void 0 ? void 0 : _b.analytics_callback;
|
|
@@ -3784,6 +4034,7 @@ function setupSPANavigation(Coframe, project, config, previewVariantId, isSessio
|
|
|
3784
4034
|
let navigationAbortController = null;
|
|
3785
4035
|
observeUrlChanges(false, async (newPageUrl, _oldPageUrl) => {
|
|
3786
4036
|
var _a;
|
|
4037
|
+
sendPageLeave(Coframe);
|
|
3787
4038
|
if (navigationAbortController)
|
|
3788
4039
|
navigationAbortController.abort();
|
|
3789
4040
|
navigationAbortController = new AbortController();
|
|
@@ -144,6 +144,10 @@ interface Metric {
|
|
|
144
144
|
selector: SelectorCondition;
|
|
145
145
|
js_binder?: string;
|
|
146
146
|
}
|
|
147
|
+
interface HeatmapSettings {
|
|
148
|
+
enabled: boolean;
|
|
149
|
+
all_pages?: boolean;
|
|
150
|
+
}
|
|
147
151
|
interface ProjectSettings {
|
|
148
152
|
mutation_observer_active: boolean;
|
|
149
153
|
track_only_activated_frames?: boolean;
|
|
@@ -152,6 +156,7 @@ interface ProjectSettings {
|
|
|
152
156
|
bot_score_threshold?: number;
|
|
153
157
|
analytics_callback?: AnalyticsCallback;
|
|
154
158
|
session_replay?: SessionReplaySettings | null;
|
|
159
|
+
heatmaps?: HeatmapSettings | null;
|
|
155
160
|
}
|
|
156
161
|
interface Project {
|
|
157
162
|
org_id: string;
|
|
@@ -164,6 +164,10 @@ interface Metric {
|
|
|
164
164
|
selector: SelectorCondition;
|
|
165
165
|
js_binder?: string;
|
|
166
166
|
}
|
|
167
|
+
interface HeatmapSettings {
|
|
168
|
+
enabled: boolean;
|
|
169
|
+
all_pages?: boolean;
|
|
170
|
+
}
|
|
167
171
|
interface ProjectSettings {
|
|
168
172
|
mutation_observer_active: boolean;
|
|
169
173
|
track_only_activated_frames?: boolean;
|
|
@@ -172,6 +176,7 @@ interface ProjectSettings {
|
|
|
172
176
|
bot_score_threshold?: number;
|
|
173
177
|
analytics_callback?: AnalyticsCallback;
|
|
174
178
|
session_replay?: SessionReplaySettings | null;
|
|
179
|
+
heatmaps?: HeatmapSettings | null;
|
|
175
180
|
}
|
|
176
181
|
interface Project {
|
|
177
182
|
org_id: string;
|
|
@@ -110,6 +110,10 @@ interface Metric {
|
|
|
110
110
|
selector: SelectorCondition;
|
|
111
111
|
js_binder?: string;
|
|
112
112
|
}
|
|
113
|
+
interface HeatmapSettings {
|
|
114
|
+
enabled: boolean;
|
|
115
|
+
all_pages?: boolean;
|
|
116
|
+
}
|
|
113
117
|
interface ProjectSettings {
|
|
114
118
|
mutation_observer_active: boolean;
|
|
115
119
|
track_only_activated_frames?: boolean;
|
|
@@ -118,6 +122,7 @@ interface ProjectSettings {
|
|
|
118
122
|
bot_score_threshold?: number;
|
|
119
123
|
analytics_callback?: AnalyticsCallback;
|
|
120
124
|
session_replay?: SessionReplaySettings | null;
|
|
125
|
+
heatmaps?: HeatmapSettings | null;
|
|
121
126
|
}
|
|
122
127
|
interface Project {
|
|
123
128
|
org_id: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coframe/sdk",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.41",
|
|
4
4
|
"description": "Coframe optimizes your website using generative AI to deliver maximum impact to your audience and allow your site to improve itself as you sleep. Learn more at coframe.com.",
|
|
5
5
|
"main": "dist/pkg/cf.cjs.js",
|
|
6
6
|
"module": "dist/pkg/cf.esm.mjs",
|