@aranova/tracking-react 0.14.2 → 0.16.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 +63 -46
- package/dist/index.d.mts +225 -103
- package/dist/index.d.ts +225 -103
- package/dist/index.js +474 -144
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +468 -144
- package/dist/index.mjs.map +1 -1
- package/dist/{phone-utils-Dyk0F14_.d.mts → phone-utils-DlAQK-gU.d.mts} +127 -6
- package/dist/{phone-utils-Dyk0F14_.d.ts → phone-utils-DlAQK-gU.d.ts} +127 -6
- package/dist/phone.d.mts +1 -1
- package/dist/phone.d.ts +1 -1
- package/dist/phone.js +88 -135
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +88 -135
- package/dist/phone.mjs.map +1 -1
- package/dist/sales.js +33 -29
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +33 -29
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -7,13 +7,30 @@ import { useCallback, useEffect, useState } from "react";
|
|
|
7
7
|
// ../tracking-core/src/consent.ts
|
|
8
8
|
var CONSENT_STATE_KEY = "consent_state";
|
|
9
9
|
var CONSENT_TIMESTAMP_KEY = "consent_timestamp";
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
var CONSENT_EXPIRES_AT_KEY = "consent_expires_at";
|
|
11
|
+
var DEFAULT_DECLINE_TTL_DAYS = 90;
|
|
12
|
+
var DAY_MS = 864e5;
|
|
13
|
+
var DEFAULT_CHOICE = {
|
|
14
|
+
state: "granted",
|
|
15
|
+
source: "default",
|
|
16
|
+
updatedAt: null,
|
|
17
|
+
expiresAt: null
|
|
18
|
+
};
|
|
19
|
+
var changeListeners = /* @__PURE__ */ new Set();
|
|
20
|
+
function onConsentChange(listener) {
|
|
21
|
+
changeListeners.add(listener);
|
|
13
22
|
return () => {
|
|
14
|
-
|
|
23
|
+
changeListeners.delete(listener);
|
|
15
24
|
};
|
|
16
25
|
}
|
|
26
|
+
function notifyConsentChanged(choice) {
|
|
27
|
+
for (const listener of changeListeners) {
|
|
28
|
+
try {
|
|
29
|
+
listener(choice);
|
|
30
|
+
} catch {
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
17
34
|
function buildConsentPayload(state) {
|
|
18
35
|
return {
|
|
19
36
|
ad_storage: state,
|
|
@@ -22,47 +39,74 @@ function buildConsentPayload(state) {
|
|
|
22
39
|
analytics_storage: state
|
|
23
40
|
};
|
|
24
41
|
}
|
|
25
|
-
function
|
|
26
|
-
if (typeof window === "undefined") return
|
|
42
|
+
function getConsentChoice() {
|
|
43
|
+
if (typeof window === "undefined") return DEFAULT_CHOICE;
|
|
27
44
|
try {
|
|
28
|
-
const
|
|
29
|
-
|
|
45
|
+
const stored = window.localStorage.getItem(CONSENT_STATE_KEY);
|
|
46
|
+
const updatedAt = window.localStorage.getItem(CONSENT_TIMESTAMP_KEY);
|
|
47
|
+
if (stored === "granted")
|
|
48
|
+
return { state: "granted", source: "explicit", updatedAt, expiresAt: null };
|
|
49
|
+
if (stored === "denied") {
|
|
50
|
+
let expiresAt = window.localStorage.getItem(CONSENT_EXPIRES_AT_KEY);
|
|
51
|
+
if (!expiresAt) {
|
|
52
|
+
expiresAt = new Date(Date.now() + DEFAULT_DECLINE_TTL_DAYS * DAY_MS).toISOString();
|
|
53
|
+
try {
|
|
54
|
+
window.localStorage.setItem(CONSENT_EXPIRES_AT_KEY, expiresAt);
|
|
55
|
+
} catch {
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!(Date.parse(expiresAt) <= Date.now()))
|
|
59
|
+
return { state: "denied", source: "explicit", updatedAt, expiresAt };
|
|
60
|
+
}
|
|
30
61
|
} catch {
|
|
31
62
|
}
|
|
32
|
-
return
|
|
63
|
+
return DEFAULT_CHOICE;
|
|
33
64
|
}
|
|
34
|
-
function
|
|
65
|
+
function getConsentState() {
|
|
66
|
+
return getConsentChoice().state;
|
|
67
|
+
}
|
|
68
|
+
function pushConsentToPlatforms(state) {
|
|
35
69
|
if (typeof window === "undefined") return;
|
|
36
|
-
try {
|
|
37
|
-
window.localStorage.setItem(CONSENT_STATE_KEY, state);
|
|
38
|
-
window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
|
|
39
|
-
} catch {
|
|
40
|
-
}
|
|
41
70
|
if (typeof window.gtag === "function")
|
|
42
71
|
window.gtag("consent", "update", buildConsentPayload(state));
|
|
43
72
|
if (typeof window.fbq === "function")
|
|
44
73
|
window.fbq("consent", state === "granted" ? "grant" : "revoke");
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
74
|
+
}
|
|
75
|
+
function setConsentState(state, options) {
|
|
76
|
+
if (typeof window === "undefined") return;
|
|
77
|
+
const requestedTtl = options?.declineTtlDays;
|
|
78
|
+
const ttlDays = typeof requestedTtl === "number" && Number.isFinite(requestedTtl) && requestedTtl > 0 ? requestedTtl : DEFAULT_DECLINE_TTL_DAYS;
|
|
79
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
80
|
+
const expiresAt = state === "denied" ? new Date(Date.now() + ttlDays * DAY_MS).toISOString() : null;
|
|
81
|
+
try {
|
|
82
|
+
window.localStorage.setItem(CONSENT_STATE_KEY, state);
|
|
83
|
+
window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, updatedAt);
|
|
84
|
+
if (expiresAt !== null) {
|
|
85
|
+
window.localStorage.setItem(CONSENT_EXPIRES_AT_KEY, expiresAt);
|
|
86
|
+
} else {
|
|
87
|
+
window.localStorage.removeItem(CONSENT_EXPIRES_AT_KEY);
|
|
51
88
|
}
|
|
89
|
+
} catch {
|
|
52
90
|
}
|
|
91
|
+
pushConsentToPlatforms(state);
|
|
92
|
+
notifyConsentChanged({ state, source: "explicit", updatedAt, expiresAt });
|
|
93
|
+
}
|
|
94
|
+
function optIn() {
|
|
95
|
+
setConsentState("granted");
|
|
96
|
+
}
|
|
97
|
+
function optOut(options) {
|
|
98
|
+
setConsentState("denied", options);
|
|
53
99
|
}
|
|
54
100
|
function resetConsent() {
|
|
55
101
|
if (typeof window === "undefined") return;
|
|
56
102
|
try {
|
|
57
103
|
window.localStorage.removeItem(CONSENT_STATE_KEY);
|
|
58
104
|
window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
|
|
105
|
+
window.localStorage.removeItem(CONSENT_EXPIRES_AT_KEY);
|
|
59
106
|
} catch {
|
|
60
107
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const consentState = getConsentState();
|
|
64
|
-
if (consentState === "granted" || consentState === "denied") setConsentState(consentState);
|
|
65
|
-
return consentState;
|
|
108
|
+
pushConsentToPlatforms("granted");
|
|
109
|
+
notifyConsentChanged(DEFAULT_CHOICE);
|
|
66
110
|
}
|
|
67
111
|
|
|
68
112
|
// ../tracking-core/src/tracking.ts
|
|
@@ -206,13 +250,11 @@ function fireGtagConversion(input) {
|
|
|
206
250
|
}
|
|
207
251
|
function applyDefaultConsentState() {
|
|
208
252
|
const gtag = ensureGtagFunction();
|
|
209
|
-
gtag(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
wait_for_update: 500
|
|
215
|
-
});
|
|
253
|
+
gtag(
|
|
254
|
+
"consent",
|
|
255
|
+
"default",
|
|
256
|
+
buildConsentPayload(getConsentState() === "denied" ? "denied" : "granted")
|
|
257
|
+
);
|
|
216
258
|
}
|
|
217
259
|
function loadGtagScript(gtagId) {
|
|
218
260
|
if (typeof document === "undefined") return;
|
|
@@ -238,7 +280,6 @@ function bootstrapGoogleAdsTracking(gtagId) {
|
|
|
238
280
|
applyDefaultConsentState();
|
|
239
281
|
loadGtagScript(gtagId);
|
|
240
282
|
initializeGtag(gtagId);
|
|
241
|
-
restoreStoredConsent();
|
|
242
283
|
}
|
|
243
284
|
function bootstrapMultipleGtags(gtagIds) {
|
|
244
285
|
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
@@ -253,7 +294,6 @@ function bootstrapMultipleGtags(gtagIds) {
|
|
|
253
294
|
for (const id of ids) {
|
|
254
295
|
gtag("config", id);
|
|
255
296
|
}
|
|
256
|
-
restoreStoredConsent();
|
|
257
297
|
}
|
|
258
298
|
|
|
259
299
|
// ../tracking-core/src/fbq.ts
|
|
@@ -313,7 +353,7 @@ function ensureFbqFunction() {
|
|
|
313
353
|
return fbq;
|
|
314
354
|
}
|
|
315
355
|
function applyDefaultMetaConsentState() {
|
|
316
|
-
ensureFbqFunction()("consent", "revoke");
|
|
356
|
+
ensureFbqFunction()("consent", getConsentState() === "denied" ? "revoke" : "grant");
|
|
317
357
|
}
|
|
318
358
|
function loadFbeventsScript() {
|
|
319
359
|
if (typeof document === "undefined") return;
|
|
@@ -333,19 +373,12 @@ function initializeMetaPixel(pixelId) {
|
|
|
333
373
|
fbq("init", pixelId);
|
|
334
374
|
fbq("track", "PageView");
|
|
335
375
|
}
|
|
336
|
-
function restoreMetaConsentState() {
|
|
337
|
-
if (typeof window === "undefined") return;
|
|
338
|
-
const state = getConsentState();
|
|
339
|
-
if (state === "granted") window.fbq?.("consent", "grant");
|
|
340
|
-
else if (state === "denied") window.fbq?.("consent", "revoke");
|
|
341
|
-
}
|
|
342
376
|
function bootstrapMetaPixel(pixelId) {
|
|
343
377
|
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
344
378
|
if (!isValidMetaPixelId(pixelId)) return;
|
|
345
379
|
applyDefaultMetaConsentState();
|
|
346
380
|
loadFbeventsScript();
|
|
347
381
|
initializeMetaPixel(pixelId);
|
|
348
|
-
restoreMetaConsentState();
|
|
349
382
|
captureFbc();
|
|
350
383
|
}
|
|
351
384
|
function bootstrapMultiplePixels(pixelIds) {
|
|
@@ -361,10 +394,75 @@ function bootstrapMultiplePixels(pixelIds) {
|
|
|
361
394
|
fbq("init", id);
|
|
362
395
|
}
|
|
363
396
|
fbq("track", "PageView");
|
|
364
|
-
restoreMetaConsentState();
|
|
365
397
|
captureFbc();
|
|
366
398
|
}
|
|
367
399
|
|
|
400
|
+
// ../tracking-core/src/landing.ts
|
|
401
|
+
var LANDING_STORAGE_KEY = "_aranova_track_landing";
|
|
402
|
+
var memoryRecord = null;
|
|
403
|
+
function sanitizeParams(value) {
|
|
404
|
+
if (typeof value !== "object" || value === null) return {};
|
|
405
|
+
const source = value;
|
|
406
|
+
return TRACKING_PARAM_KEYS.reduce((params, key) => {
|
|
407
|
+
const entry = source[key];
|
|
408
|
+
if (typeof entry === "string" && entry.length > 0) params[key] = entry;
|
|
409
|
+
return params;
|
|
410
|
+
}, {});
|
|
411
|
+
}
|
|
412
|
+
function readStoredRecord() {
|
|
413
|
+
try {
|
|
414
|
+
const raw = window.localStorage.getItem(LANDING_STORAGE_KEY);
|
|
415
|
+
if (!raw) return null;
|
|
416
|
+
const parsed = JSON.parse(raw);
|
|
417
|
+
if (typeof parsed.session_id !== "string" || parsed.session_id.length === 0) return null;
|
|
418
|
+
return { session_id: parsed.session_id, params: sanitizeParams(parsed.params) };
|
|
419
|
+
} catch {
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
function writeRecord(record) {
|
|
424
|
+
memoryRecord = record;
|
|
425
|
+
try {
|
|
426
|
+
window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record));
|
|
427
|
+
} catch {
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
function captureFromUrl(url) {
|
|
431
|
+
try {
|
|
432
|
+
const resolved = new URL(url ?? window.location.href, window.location.origin);
|
|
433
|
+
return getTrackingQueryValues(resolved.searchParams);
|
|
434
|
+
} catch {
|
|
435
|
+
return {};
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function getOrCaptureLandingParams(sessionId, url) {
|
|
439
|
+
if (typeof window === "undefined") return {};
|
|
440
|
+
const stored = readStoredRecord();
|
|
441
|
+
if (stored && stored.session_id === sessionId) {
|
|
442
|
+
memoryRecord = stored;
|
|
443
|
+
return stored.params;
|
|
444
|
+
}
|
|
445
|
+
if (memoryRecord && memoryRecord.session_id === sessionId) {
|
|
446
|
+
return memoryRecord.params;
|
|
447
|
+
}
|
|
448
|
+
const record = { session_id: sessionId, params: captureFromUrl(url) };
|
|
449
|
+
writeRecord(record);
|
|
450
|
+
return record.params;
|
|
451
|
+
}
|
|
452
|
+
function buildLandingPayloadFields(sessionId, override) {
|
|
453
|
+
const params = override ?? (typeof window === "undefined" ? null : getOrCaptureLandingParams(sessionId));
|
|
454
|
+
if (params === null) return {};
|
|
455
|
+
return {
|
|
456
|
+
landing_gclid: params.gclid ?? null,
|
|
457
|
+
landing_fbclid: params.fbclid ?? null,
|
|
458
|
+
landing_utm_source: params.utm_source ?? null,
|
|
459
|
+
landing_utm_medium: params.utm_medium ?? null,
|
|
460
|
+
landing_utm_campaign: params.utm_campaign ?? null,
|
|
461
|
+
landing_utm_term: params.utm_term ?? null,
|
|
462
|
+
landing_utm_content: params.utm_content ?? null
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
368
466
|
// ../tracking-core/src/payloads.ts
|
|
369
467
|
function createTrackingClientContext(surface, input = {}) {
|
|
370
468
|
return {
|
|
@@ -391,6 +489,9 @@ function createTrackingSessionUpsertPayload(trackingParams, input, context) {
|
|
|
391
489
|
utm_campaign: trackingParams.utm_campaign,
|
|
392
490
|
utm_term: trackingParams.utm_term,
|
|
393
491
|
utm_content: trackingParams.utm_content,
|
|
492
|
+
// Omitted entirely when the landing isn't observable (SSR, no override) —
|
|
493
|
+
// present-as-null would wrongly tell the backend "landed with no params".
|
|
494
|
+
...buildLandingPayloadFields(input.sessionId, input.landingParams),
|
|
394
495
|
first_page: input.firstPage ?? null,
|
|
395
496
|
consent_state: input.consentState ?? null,
|
|
396
497
|
context
|
|
@@ -412,8 +513,6 @@ function createTrackingEventCreatePayload(trackingParams, input, context) {
|
|
|
412
513
|
|
|
413
514
|
// ../tracking-core/src/resources/conversion-firing.ts
|
|
414
515
|
var DEDUP_PREFIX = "_aranova_conv_";
|
|
415
|
-
var MAX_PENDING = 100;
|
|
416
|
-
var pendingQueue = [];
|
|
417
516
|
function dedupKey(input) {
|
|
418
517
|
return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
|
|
419
518
|
}
|
|
@@ -437,23 +536,9 @@ function fireOnce(input) {
|
|
|
437
536
|
if (fireGtagConversion(input)) markFired(input);
|
|
438
537
|
}
|
|
439
538
|
function fireConversionWithConsent(input) {
|
|
440
|
-
|
|
441
|
-
if (state === "denied") return;
|
|
442
|
-
if (state === "pending") {
|
|
443
|
-
if (pendingQueue.length >= MAX_PENDING) pendingQueue.shift();
|
|
444
|
-
pendingQueue.push(input);
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
539
|
+
if (getConsentState() === "denied") return;
|
|
447
540
|
fireOnce(input);
|
|
448
541
|
}
|
|
449
|
-
function flushPendingConversions() {
|
|
450
|
-
if (getConsentState() !== "granted") return;
|
|
451
|
-
while (pendingQueue.length > 0) {
|
|
452
|
-
const input = pendingQueue.shift();
|
|
453
|
-
if (input) fireOnce(input);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
if (typeof window !== "undefined") onConsentGranted(flushPendingConversions);
|
|
457
542
|
|
|
458
543
|
// ../tracking-core/src/resources/conversion-config.ts
|
|
459
544
|
function isStringMap(value) {
|
|
@@ -999,7 +1084,13 @@ function readTrackingParams() {
|
|
|
999
1084
|
}
|
|
1000
1085
|
function consentSnapshot() {
|
|
1001
1086
|
try {
|
|
1002
|
-
|
|
1087
|
+
const choice = getConsentChoice();
|
|
1088
|
+
return {
|
|
1089
|
+
state: choice.state,
|
|
1090
|
+
source: choice.source,
|
|
1091
|
+
updated_at: choice.updatedAt,
|
|
1092
|
+
expires_at: choice.expiresAt
|
|
1093
|
+
};
|
|
1003
1094
|
} catch {
|
|
1004
1095
|
return null;
|
|
1005
1096
|
}
|
|
@@ -1072,6 +1163,7 @@ function createTrackingClient(config) {
|
|
|
1072
1163
|
initialParams = captureTrackingParamsFromLocation();
|
|
1073
1164
|
} catch {
|
|
1074
1165
|
}
|
|
1166
|
+
getOrCaptureLandingParams(sessionId);
|
|
1075
1167
|
try {
|
|
1076
1168
|
captureFbc();
|
|
1077
1169
|
} catch {
|
|
@@ -1121,6 +1213,11 @@ function createTrackingClient(config) {
|
|
|
1121
1213
|
utm_campaign: params.utm_campaign,
|
|
1122
1214
|
utm_term: params.utm_term,
|
|
1123
1215
|
utm_content: params.utm_content,
|
|
1216
|
+
// Landing params for the CURRENT session id — captured on the spot when
|
|
1217
|
+
// the session just rotated (the current URL is the rotated session's
|
|
1218
|
+
// landing), reused from the stored record otherwise. Keys are omitted
|
|
1219
|
+
// entirely when the landing isn't observable (SSR).
|
|
1220
|
+
...buildLandingPayloadFields(sessionId),
|
|
1124
1221
|
first_page: firstPage,
|
|
1125
1222
|
consent_state: consentSnapshot(),
|
|
1126
1223
|
context
|
|
@@ -1188,6 +1285,7 @@ function createTrackingClient(config) {
|
|
|
1188
1285
|
return {
|
|
1189
1286
|
trackEvent,
|
|
1190
1287
|
flush,
|
|
1288
|
+
flushBeacon: flushOnUnload,
|
|
1191
1289
|
getSessionId: () => sessionId,
|
|
1192
1290
|
getVisitorId: () => visitorId,
|
|
1193
1291
|
destroy: () => {
|
|
@@ -1212,9 +1310,17 @@ var ctaClickMetadataSchema = z2.object({
|
|
|
1212
1310
|
path: z2.string()
|
|
1213
1311
|
}).strict(),
|
|
1214
1312
|
section: z2.string().nullable().optional(),
|
|
1215
|
-
destination_url: z2.string().nullable().optional()
|
|
1313
|
+
destination_url: z2.string().nullable().optional(),
|
|
1314
|
+
// Set by auto-capture (and available to manual callers): the link target
|
|
1315
|
+
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
1316
|
+
href: z2.string().nullable().optional(),
|
|
1317
|
+
element: z2.string().nullable().optional()
|
|
1318
|
+
}).strict();
|
|
1319
|
+
var ctaClickConfigSchema = z2.object({
|
|
1320
|
+
autoCapture: z2.object({
|
|
1321
|
+
selector: z2.string().optional()
|
|
1322
|
+
}).strict().optional()
|
|
1216
1323
|
}).strict();
|
|
1217
|
-
var ctaClickConfigSchema = z2.object({}).strict();
|
|
1218
1324
|
|
|
1219
1325
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
1220
1326
|
import { z as z3 } from "zod";
|
|
@@ -1290,31 +1396,44 @@ var multiPageSessionConfigSchema = z6.object({
|
|
|
1290
1396
|
pageThreshold: z6.number().int().min(2)
|
|
1291
1397
|
}).strict();
|
|
1292
1398
|
|
|
1293
|
-
// ../tracking-core/src/events/
|
|
1399
|
+
// ../tracking-core/src/events/page-exit.ts
|
|
1294
1400
|
import { z as z7 } from "zod";
|
|
1295
|
-
var
|
|
1296
|
-
|
|
1401
|
+
var pageExitMetadataSchema = z7.object({
|
|
1402
|
+
dwell_ms: z7.number().int().min(0),
|
|
1403
|
+
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
1404
|
+
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
1405
|
+
max_scroll_percent: z7.number().int().min(0).max(100).nullable(),
|
|
1297
1406
|
page: z7.object({
|
|
1298
1407
|
path: z7.string()
|
|
1299
|
-
}).strict()
|
|
1300
|
-
section: z7.string().nullable().optional()
|
|
1408
|
+
}).strict()
|
|
1301
1409
|
}).strict();
|
|
1302
|
-
var
|
|
1410
|
+
var pageExitConfigSchema = z7.object({}).strict();
|
|
1303
1411
|
|
|
1304
|
-
// ../tracking-core/src/events/
|
|
1412
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
1305
1413
|
import { z as z8 } from "zod";
|
|
1306
|
-
var
|
|
1307
|
-
|
|
1414
|
+
var phoneClickMetadataSchema = z8.object({
|
|
1415
|
+
phone_number: z8.string(),
|
|
1308
1416
|
page: z8.object({
|
|
1309
1417
|
path: z8.string()
|
|
1418
|
+
}).strict(),
|
|
1419
|
+
section: z8.string().nullable().optional()
|
|
1420
|
+
}).strict();
|
|
1421
|
+
var phoneClickConfigSchema = z8.object({}).strict();
|
|
1422
|
+
|
|
1423
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
1424
|
+
import { z as z9 } from "zod";
|
|
1425
|
+
var scrollDepthMetadataSchema = z9.object({
|
|
1426
|
+
depth_percent: z9.number().int().min(1).max(100),
|
|
1427
|
+
page: z9.object({
|
|
1428
|
+
path: z9.string()
|
|
1310
1429
|
}).strict()
|
|
1311
1430
|
}).strict();
|
|
1312
|
-
var scrollDepthConfigSchema =
|
|
1313
|
-
thresholds:
|
|
1431
|
+
var scrollDepthConfigSchema = z9.object({
|
|
1432
|
+
thresholds: z9.array(z9.number().int().min(1).max(100)).min(1)
|
|
1314
1433
|
}).strict();
|
|
1315
1434
|
|
|
1316
1435
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
1317
|
-
import { z as
|
|
1436
|
+
import { z as z10 } from "zod";
|
|
1318
1437
|
var SPECIFIC_PAGE_NAMES = [
|
|
1319
1438
|
"contact_page",
|
|
1320
1439
|
"about_page",
|
|
@@ -1325,18 +1444,18 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
1325
1444
|
"faq_page",
|
|
1326
1445
|
"testimonials_page"
|
|
1327
1446
|
];
|
|
1328
|
-
var specificPageNameSchema =
|
|
1329
|
-
var specificPageVisitMetadataSchema =
|
|
1447
|
+
var specificPageNameSchema = z10.enum(SPECIFIC_PAGE_NAMES);
|
|
1448
|
+
var specificPageVisitMetadataSchema = z10.object({
|
|
1330
1449
|
page_name: specificPageNameSchema,
|
|
1331
|
-
page:
|
|
1332
|
-
path:
|
|
1450
|
+
page: z10.object({
|
|
1451
|
+
path: z10.string()
|
|
1333
1452
|
}).strict()
|
|
1334
1453
|
}).strict();
|
|
1335
|
-
var specificPageVisitConfigSchema =
|
|
1336
|
-
pages:
|
|
1337
|
-
|
|
1454
|
+
var specificPageVisitConfigSchema = z10.object({
|
|
1455
|
+
pages: z10.array(
|
|
1456
|
+
z10.object({
|
|
1338
1457
|
name: specificPageNameSchema,
|
|
1339
|
-
pathPattern:
|
|
1458
|
+
pathPattern: z10.custom((value) => value instanceof RegExp, {
|
|
1340
1459
|
message: "pathPattern must be a RegExp"
|
|
1341
1460
|
})
|
|
1342
1461
|
}).strict()
|
|
@@ -1344,15 +1463,15 @@ var specificPageVisitConfigSchema = z9.object({
|
|
|
1344
1463
|
}).strict();
|
|
1345
1464
|
|
|
1346
1465
|
// ../tracking-core/src/events/time-on-site.ts
|
|
1347
|
-
import { z as
|
|
1348
|
-
var timeOnSiteMetadataSchema =
|
|
1349
|
-
duration_ms:
|
|
1350
|
-
page:
|
|
1351
|
-
path:
|
|
1466
|
+
import { z as z11 } from "zod";
|
|
1467
|
+
var timeOnSiteMetadataSchema = z11.object({
|
|
1468
|
+
duration_ms: z11.number().int().nonnegative(),
|
|
1469
|
+
page: z11.object({
|
|
1470
|
+
path: z11.string()
|
|
1352
1471
|
}).strict()
|
|
1353
1472
|
}).strict();
|
|
1354
|
-
var timeOnSiteConfigSchema =
|
|
1355
|
-
thresholdSeconds:
|
|
1473
|
+
var timeOnSiteConfigSchema = z11.object({
|
|
1474
|
+
thresholdSeconds: z11.number().int().positive()
|
|
1356
1475
|
}).strict();
|
|
1357
1476
|
|
|
1358
1477
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -1394,6 +1513,11 @@ var EVENT_REGISTRY = {
|
|
|
1394
1513
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
1395
1514
|
configSchema: sdkHeartbeatConfigSchema
|
|
1396
1515
|
},
|
|
1516
|
+
page_exit: {
|
|
1517
|
+
kind: "automatic",
|
|
1518
|
+
metadataSchema: pageExitMetadataSchema,
|
|
1519
|
+
configSchema: pageExitConfigSchema
|
|
1520
|
+
},
|
|
1397
1521
|
// --- manual triggers ---
|
|
1398
1522
|
form_submit: {
|
|
1399
1523
|
kind: "manual",
|
|
@@ -1772,6 +1896,163 @@ function attachFormStart(client, config) {
|
|
|
1772
1896
|
};
|
|
1773
1897
|
}
|
|
1774
1898
|
|
|
1899
|
+
// ../tracking-core/src/triggers/page-exit.ts
|
|
1900
|
+
function attachPageExit(client) {
|
|
1901
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1902
|
+
return () => {
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1905
|
+
let currentPath2 = window.location.pathname;
|
|
1906
|
+
let activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1907
|
+
let accumulatedMs = 0;
|
|
1908
|
+
let maxScrollPercent = null;
|
|
1909
|
+
let rafId = null;
|
|
1910
|
+
function getScrollPercent() {
|
|
1911
|
+
const doc = document.documentElement;
|
|
1912
|
+
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1913
|
+
const scrollHeight = doc.scrollHeight;
|
|
1914
|
+
const clientHeight = doc.clientHeight;
|
|
1915
|
+
if (scrollHeight <= clientHeight) return 100;
|
|
1916
|
+
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1917
|
+
}
|
|
1918
|
+
function onScroll() {
|
|
1919
|
+
if (rafId !== null) return;
|
|
1920
|
+
rafId = requestAnimationFrame(() => {
|
|
1921
|
+
rafId = null;
|
|
1922
|
+
const percent = getScrollPercent();
|
|
1923
|
+
if (percent >= 1 && (maxScrollPercent === null || percent > maxScrollPercent)) {
|
|
1924
|
+
maxScrollPercent = Math.min(percent, 100);
|
|
1925
|
+
}
|
|
1926
|
+
});
|
|
1927
|
+
}
|
|
1928
|
+
function settledDwellMs() {
|
|
1929
|
+
let total = accumulatedMs;
|
|
1930
|
+
if (activeSince !== null) {
|
|
1931
|
+
total += Date.now() - activeSince;
|
|
1932
|
+
}
|
|
1933
|
+
return Math.max(0, Math.round(total));
|
|
1934
|
+
}
|
|
1935
|
+
function emitSegment(path, flush) {
|
|
1936
|
+
const dwell = settledDwellMs();
|
|
1937
|
+
if (dwell === 0) return;
|
|
1938
|
+
client.trackEvent({
|
|
1939
|
+
eventType: "page_exit",
|
|
1940
|
+
metadata: {
|
|
1941
|
+
dwell_ms: dwell,
|
|
1942
|
+
max_scroll_percent: maxScrollPercent,
|
|
1943
|
+
page: { path }
|
|
1944
|
+
},
|
|
1945
|
+
pageUrl: window.location.href,
|
|
1946
|
+
occurredAt: null
|
|
1947
|
+
});
|
|
1948
|
+
if (flush) {
|
|
1949
|
+
client.flushBeacon();
|
|
1950
|
+
}
|
|
1951
|
+
accumulatedMs = 0;
|
|
1952
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1953
|
+
}
|
|
1954
|
+
function onNavigate() {
|
|
1955
|
+
const newPath = window.location.pathname;
|
|
1956
|
+
if (newPath === currentPath2) return;
|
|
1957
|
+
emitSegment(currentPath2, false);
|
|
1958
|
+
currentPath2 = newPath;
|
|
1959
|
+
maxScrollPercent = null;
|
|
1960
|
+
accumulatedMs = 0;
|
|
1961
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1962
|
+
}
|
|
1963
|
+
function onVisibilityChange() {
|
|
1964
|
+
if (document.visibilityState === "hidden") {
|
|
1965
|
+
emitSegment(currentPath2, true);
|
|
1966
|
+
} else {
|
|
1967
|
+
activeSince = Date.now();
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
function onPageHide() {
|
|
1971
|
+
emitSegment(currentPath2, true);
|
|
1972
|
+
}
|
|
1973
|
+
const originalPushState = history.pushState.bind(history);
|
|
1974
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
1975
|
+
function patchedPushState(...args) {
|
|
1976
|
+
originalPushState(...args);
|
|
1977
|
+
setTimeout(onNavigate, 0);
|
|
1978
|
+
}
|
|
1979
|
+
function patchedReplaceState(...args) {
|
|
1980
|
+
originalReplaceState(...args);
|
|
1981
|
+
setTimeout(onNavigate, 0);
|
|
1982
|
+
}
|
|
1983
|
+
history.pushState = patchedPushState;
|
|
1984
|
+
history.replaceState = patchedReplaceState;
|
|
1985
|
+
window.addEventListener("popstate", onNavigate);
|
|
1986
|
+
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1987
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1988
|
+
window.addEventListener("pagehide", onPageHide);
|
|
1989
|
+
return () => {
|
|
1990
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1991
|
+
history.pushState = originalPushState;
|
|
1992
|
+
history.replaceState = originalReplaceState;
|
|
1993
|
+
window.removeEventListener("popstate", onNavigate);
|
|
1994
|
+
window.removeEventListener("scroll", onScroll);
|
|
1995
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1996
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
// ../tracking-core/src/triggers/cta-click-capture.ts
|
|
2001
|
+
var DEFAULT_CTA_SELECTOR = "[data-aranova-cta]";
|
|
2002
|
+
var CTA_NAME_MAX_LENGTH = 120;
|
|
2003
|
+
function describeElement(el) {
|
|
2004
|
+
const tag = el.tagName.toLowerCase();
|
|
2005
|
+
return el.id ? `${tag}#${el.id}` : tag;
|
|
2006
|
+
}
|
|
2007
|
+
function resolveCtaName(el) {
|
|
2008
|
+
const explicit = el.getAttribute("data-aranova-cta");
|
|
2009
|
+
if (explicit && explicit.trim().length > 0) return explicit.trim();
|
|
2010
|
+
const text = (el.textContent ?? "").trim().replace(/\s+/g, " ");
|
|
2011
|
+
if (text.length > 0) return text.slice(0, CTA_NAME_MAX_LENGTH);
|
|
2012
|
+
return describeElement(el);
|
|
2013
|
+
}
|
|
2014
|
+
function attachCtaClickCapture(client, config) {
|
|
2015
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
2016
|
+
return () => {
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
const autoCapture = config.autoCapture;
|
|
2020
|
+
if (!autoCapture) {
|
|
2021
|
+
return () => {
|
|
2022
|
+
};
|
|
2023
|
+
}
|
|
2024
|
+
const selector = autoCapture.selector ?? DEFAULT_CTA_SELECTOR;
|
|
2025
|
+
function onClick(event) {
|
|
2026
|
+
const target = event.target;
|
|
2027
|
+
if (!(target instanceof Element)) return;
|
|
2028
|
+
let matched = null;
|
|
2029
|
+
try {
|
|
2030
|
+
matched = target.closest(selector);
|
|
2031
|
+
} catch {
|
|
2032
|
+
return;
|
|
2033
|
+
}
|
|
2034
|
+
if (matched === null) return;
|
|
2035
|
+
const href = matched instanceof HTMLAnchorElement ? matched.href || null : matched.getAttribute("href");
|
|
2036
|
+
client.trackEvent({
|
|
2037
|
+
eventType: "cta_click",
|
|
2038
|
+
metadata: {
|
|
2039
|
+
cta_name: resolveCtaName(matched),
|
|
2040
|
+
page: { path: window.location.pathname },
|
|
2041
|
+
section: matched.getAttribute("data-aranova-section"),
|
|
2042
|
+
destination_url: href,
|
|
2043
|
+
href,
|
|
2044
|
+
element: describeElement(matched)
|
|
2045
|
+
},
|
|
2046
|
+
pageUrl: window.location.href,
|
|
2047
|
+
occurredAt: null
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
document.addEventListener("click", onClick, true);
|
|
2051
|
+
return () => {
|
|
2052
|
+
document.removeEventListener("click", onClick, true);
|
|
2053
|
+
};
|
|
2054
|
+
}
|
|
2055
|
+
|
|
1775
2056
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
1776
2057
|
var AranovaApiError = class extends Error {
|
|
1777
2058
|
constructor(message, options) {
|
|
@@ -1978,42 +2259,42 @@ function createSalesClient(config) {
|
|
|
1978
2259
|
}
|
|
1979
2260
|
|
|
1980
2261
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
1981
|
-
import { z as
|
|
2262
|
+
import { z as z12 } from "zod";
|
|
1982
2263
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
1983
2264
|
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
1984
|
-
var currencySchema =
|
|
1985
|
-
var centsSchema =
|
|
1986
|
-
var quantitySchema =
|
|
1987
|
-
var metadataSchema =
|
|
1988
|
-
var saleItemSchema =
|
|
1989
|
-
external_item_id:
|
|
1990
|
-
name:
|
|
1991
|
-
category:
|
|
2265
|
+
var currencySchema = z12.enum(SUPPORTED_CURRENCIES);
|
|
2266
|
+
var centsSchema = z12.number().int().nonnegative();
|
|
2267
|
+
var quantitySchema = z12.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
2268
|
+
var metadataSchema = z12.record(z12.unknown());
|
|
2269
|
+
var saleItemSchema = z12.object({
|
|
2270
|
+
external_item_id: z12.string().nullable().optional(),
|
|
2271
|
+
name: z12.string().nullable().optional(),
|
|
2272
|
+
category: z12.string().nullable().optional(),
|
|
1992
2273
|
quantity: quantitySchema,
|
|
1993
2274
|
unit_price_cents: centsSchema,
|
|
1994
2275
|
// Non-negativity validated on the wire — same contract as the other cents
|
|
1995
2276
|
// fields — and backstopped by the DB CHECK.
|
|
1996
2277
|
unit_cost_cents: centsSchema.nullable().optional()
|
|
1997
2278
|
}).strict();
|
|
1998
|
-
var saleServiceSchema =
|
|
1999
|
-
service:
|
|
2279
|
+
var saleServiceSchema = z12.object({
|
|
2280
|
+
service: z12.string(),
|
|
2000
2281
|
amount_cents: centsSchema
|
|
2001
2282
|
}).strict();
|
|
2002
|
-
var customerNameSchema =
|
|
2003
|
-
var customerPhoneSchema =
|
|
2004
|
-
var customerEmailSchema =
|
|
2283
|
+
var customerNameSchema = z12.string().max(200);
|
|
2284
|
+
var customerPhoneSchema = z12.string().max(64);
|
|
2285
|
+
var customerEmailSchema = z12.string().max(320).email();
|
|
2005
2286
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
2006
2287
|
if (val.services != null) {
|
|
2007
2288
|
if (val.service != null) {
|
|
2008
2289
|
ctx.addIssue({
|
|
2009
|
-
code:
|
|
2290
|
+
code: z12.ZodIssueCode.custom,
|
|
2010
2291
|
message: "pass either `service` or `services`, not both",
|
|
2011
2292
|
path: ["services"]
|
|
2012
2293
|
});
|
|
2013
2294
|
}
|
|
2014
2295
|
if (val.services.length === 0) {
|
|
2015
2296
|
ctx.addIssue({
|
|
2016
|
-
code:
|
|
2297
|
+
code: z12.ZodIssueCode.custom,
|
|
2017
2298
|
message: "`services` must not be empty",
|
|
2018
2299
|
path: ["services"]
|
|
2019
2300
|
});
|
|
@@ -2021,7 +2302,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
2021
2302
|
const keys = val.services.map((s) => s.service);
|
|
2022
2303
|
if (new Set(keys).size !== keys.length) {
|
|
2023
2304
|
ctx.addIssue({
|
|
2024
|
-
code:
|
|
2305
|
+
code: z12.ZodIssueCode.custom,
|
|
2025
2306
|
message: "`services` must not list the same service more than once",
|
|
2026
2307
|
path: ["services"]
|
|
2027
2308
|
});
|
|
@@ -2030,7 +2311,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
2030
2311
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
2031
2312
|
if (val.amount_total_cents !== sum) {
|
|
2032
2313
|
ctx.addIssue({
|
|
2033
|
-
code:
|
|
2314
|
+
code: z12.ZodIssueCode.custom,
|
|
2034
2315
|
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
2035
2316
|
path: ["amount_total_cents"]
|
|
2036
2317
|
});
|
|
@@ -2038,37 +2319,37 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
2038
2319
|
}
|
|
2039
2320
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
2040
2321
|
ctx.addIssue({
|
|
2041
|
-
code:
|
|
2322
|
+
code: z12.ZodIssueCode.custom,
|
|
2042
2323
|
message: "amount_total_cents is required unless `services` is provided",
|
|
2043
2324
|
path: ["amount_total_cents"]
|
|
2044
2325
|
});
|
|
2045
2326
|
}
|
|
2046
2327
|
}
|
|
2047
|
-
var saleCreateSchema =
|
|
2048
|
-
external_id:
|
|
2049
|
-
description:
|
|
2050
|
-
service:
|
|
2051
|
-
services:
|
|
2328
|
+
var saleCreateSchema = z12.object({
|
|
2329
|
+
external_id: z12.string().nullable().optional(),
|
|
2330
|
+
description: z12.string().nullable().optional(),
|
|
2331
|
+
service: z12.string().nullable().optional(),
|
|
2332
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
2052
2333
|
currency: currencySchema,
|
|
2053
2334
|
// Optional only because the plural `services` form derives it from the sum
|
|
2054
2335
|
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
2055
2336
|
amount_total_cents: centsSchema.nullable().optional(),
|
|
2056
|
-
occurred_at:
|
|
2057
|
-
environment:
|
|
2058
|
-
items:
|
|
2337
|
+
occurred_at: z12.string().datetime(),
|
|
2338
|
+
environment: z12.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
2339
|
+
items: z12.array(saleItemSchema).default([]),
|
|
2059
2340
|
metadata: metadataSchema.nullable().optional(),
|
|
2060
2341
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2061
2342
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2062
2343
|
customer_email: customerEmailSchema.nullable().optional()
|
|
2063
2344
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
2064
|
-
var saleUpdateSchema =
|
|
2065
|
-
description:
|
|
2066
|
-
service:
|
|
2067
|
-
services:
|
|
2345
|
+
var saleUpdateSchema = z12.object({
|
|
2346
|
+
description: z12.string().nullable().optional(),
|
|
2347
|
+
service: z12.string().nullable().optional(),
|
|
2348
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
2068
2349
|
currency: currencySchema.optional(),
|
|
2069
2350
|
amount_total_cents: centsSchema.optional(),
|
|
2070
|
-
occurred_at:
|
|
2071
|
-
items:
|
|
2351
|
+
occurred_at: z12.string().datetime().optional(),
|
|
2352
|
+
items: z12.array(saleItemSchema).optional(),
|
|
2072
2353
|
metadata: metadataSchema.nullable().optional(),
|
|
2073
2354
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2074
2355
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
@@ -2154,36 +2435,68 @@ function useTrackingParams() {
|
|
|
2154
2435
|
}, []);
|
|
2155
2436
|
return trackingParams;
|
|
2156
2437
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2438
|
+
var DEFAULT_CHOICE2 = {
|
|
2439
|
+
state: "granted",
|
|
2440
|
+
source: "default",
|
|
2441
|
+
updatedAt: null,
|
|
2442
|
+
expiresAt: null
|
|
2443
|
+
};
|
|
2444
|
+
function useCookiePreferences(options) {
|
|
2445
|
+
const [choice, setChoice] = useState(DEFAULT_CHOICE2);
|
|
2446
|
+
const ttlDays = options?.declineTtlDays;
|
|
2162
2447
|
useEffect(() => {
|
|
2163
|
-
|
|
2448
|
+
const sync = () => setChoice(getConsentChoice());
|
|
2449
|
+
sync();
|
|
2164
2450
|
const handleStorage = (event) => {
|
|
2165
|
-
if (event.key === CONSENT_STATE_KEY
|
|
2451
|
+
if (event.key === null || event.key === CONSENT_STATE_KEY || event.key === CONSENT_EXPIRES_AT_KEY || event.key === CONSENT_TIMESTAMP_KEY)
|
|
2452
|
+
sync();
|
|
2166
2453
|
};
|
|
2167
2454
|
window.addEventListener("storage", handleStorage);
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2455
|
+
const unsubscribe = onConsentChange(sync);
|
|
2456
|
+
return () => {
|
|
2457
|
+
window.removeEventListener("storage", handleStorage);
|
|
2458
|
+
unsubscribe();
|
|
2459
|
+
};
|
|
2173
2460
|
}, []);
|
|
2174
|
-
const
|
|
2175
|
-
|
|
2176
|
-
|
|
2461
|
+
const optOutAction = useCallback(() => {
|
|
2462
|
+
optOut(ttlDays != null ? { declineTtlDays: ttlDays } : void 0);
|
|
2463
|
+
}, [ttlDays]);
|
|
2464
|
+
const optInAction = useCallback(() => {
|
|
2465
|
+
optIn();
|
|
2177
2466
|
}, []);
|
|
2178
2467
|
const reset = useCallback(() => {
|
|
2179
2468
|
resetConsent();
|
|
2180
|
-
setState("pending");
|
|
2181
2469
|
}, []);
|
|
2470
|
+
return {
|
|
2471
|
+
state: choice.state,
|
|
2472
|
+
source: choice.source,
|
|
2473
|
+
isDefault: choice.source === "default",
|
|
2474
|
+
isGranted: choice.state === "granted",
|
|
2475
|
+
isDenied: choice.state === "denied",
|
|
2476
|
+
updatedAt: choice.updatedAt,
|
|
2477
|
+
expiresAt: choice.expiresAt,
|
|
2478
|
+
optOut: optOutAction,
|
|
2479
|
+
optIn: optInAction,
|
|
2480
|
+
reset
|
|
2481
|
+
};
|
|
2482
|
+
}
|
|
2483
|
+
function useConsentState() {
|
|
2484
|
+
return useConsent().state;
|
|
2485
|
+
}
|
|
2486
|
+
function useConsent() {
|
|
2487
|
+
const {
|
|
2488
|
+
state,
|
|
2489
|
+
isGranted,
|
|
2490
|
+
isDenied,
|
|
2491
|
+
optIn: accept,
|
|
2492
|
+
optOut: decline,
|
|
2493
|
+
reset
|
|
2494
|
+
} = useCookiePreferences();
|
|
2182
2495
|
return {
|
|
2183
2496
|
state,
|
|
2184
|
-
isPending:
|
|
2185
|
-
isGranted
|
|
2186
|
-
isDenied
|
|
2497
|
+
isPending: false,
|
|
2498
|
+
isGranted,
|
|
2499
|
+
isDenied,
|
|
2187
2500
|
accept,
|
|
2188
2501
|
decline,
|
|
2189
2502
|
reset
|
|
@@ -2424,7 +2737,7 @@ function GoogleAdsTracking(props) {
|
|
|
2424
2737
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
2425
2738
|
|
|
2426
2739
|
// package.json
|
|
2427
|
-
var version = "0.
|
|
2740
|
+
var version = "0.16.0";
|
|
2428
2741
|
|
|
2429
2742
|
// ../tracking-core/src/phone-react.tsx
|
|
2430
2743
|
import {
|
|
@@ -2612,6 +2925,7 @@ function createTracking(options) {
|
|
|
2612
2925
|
const detectorClient = conversionStore ? withConversionAutoFire(rawClient, createConversionAutoFire(conversionStore)) : rawClient;
|
|
2613
2926
|
detachers.push(attachAutoPageView(detectorClient));
|
|
2614
2927
|
detachers.push(attachBfcacheRestore(detectorClient));
|
|
2928
|
+
detachers.push(attachPageExit(detectorClient));
|
|
2615
2929
|
const timeOnSite = triggers.automatic.time_on_site;
|
|
2616
2930
|
if (timeOnSite) {
|
|
2617
2931
|
detachers.push(attachTimeOnSite(detectorClient, timeOnSite));
|
|
@@ -2632,6 +2946,10 @@ function createTracking(options) {
|
|
|
2632
2946
|
if (formStart) {
|
|
2633
2947
|
detachers.push(attachFormStart(detectorClient, formStart));
|
|
2634
2948
|
}
|
|
2949
|
+
const ctaClick = triggers.manual?.cta_click;
|
|
2950
|
+
if (ctaClick) {
|
|
2951
|
+
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2952
|
+
}
|
|
2635
2953
|
return () => {
|
|
2636
2954
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2637
2955
|
detachers[i]();
|
|
@@ -2655,6 +2973,7 @@ export {
|
|
|
2655
2973
|
AdPlatformTracking,
|
|
2656
2974
|
AranovaApiError,
|
|
2657
2975
|
ConsentBanner,
|
|
2976
|
+
DEFAULT_DECLINE_TTL_DAYS,
|
|
2658
2977
|
DEFAULT_PHONE_COUNTRY,
|
|
2659
2978
|
GoogleAdsTracking,
|
|
2660
2979
|
NAMED_RANGES,
|
|
@@ -2674,7 +2993,11 @@ export {
|
|
|
2674
2993
|
formatPhone,
|
|
2675
2994
|
formatPhoneAsTyped,
|
|
2676
2995
|
fromMinor,
|
|
2996
|
+
getConsentChoice,
|
|
2677
2997
|
getConsentState,
|
|
2998
|
+
onConsentChange,
|
|
2999
|
+
optIn,
|
|
3000
|
+
optOut,
|
|
2678
3001
|
parsePhone,
|
|
2679
3002
|
phoneField,
|
|
2680
3003
|
resetConsent,
|
|
@@ -2689,6 +3012,7 @@ export {
|
|
|
2689
3012
|
toMinor,
|
|
2690
3013
|
useConsent,
|
|
2691
3014
|
useConsentState,
|
|
3015
|
+
useCookiePreferences,
|
|
2692
3016
|
useGclid,
|
|
2693
3017
|
usePhoneConfig,
|
|
2694
3018
|
usePhoneField,
|