@aranova/tracking-next 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 +67 -50
- package/dist/index.d.mts +219 -99
- package/dist/index.d.ts +219 -99
- package/dist/index.js +490 -155
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +484 -155
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.js +88 -135
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +88 -135
- package/dist/middleware.mjs.map +1 -1
- package/dist/{phone-utils-CcU5mwzc.d.mts → phone-utils-DlAQK-gU.d.mts} +127 -6
- package/dist/{phone-utils-CcU5mwzc.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/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +88 -135
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +88 -135
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
1
|
// ../tracking-core/src/consent.ts
|
|
2
2
|
var CONSENT_STATE_KEY = "consent_state";
|
|
3
3
|
var CONSENT_TIMESTAMP_KEY = "consent_timestamp";
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
var CONSENT_EXPIRES_AT_KEY = "consent_expires_at";
|
|
5
|
+
var DEFAULT_DECLINE_TTL_DAYS = 90;
|
|
6
|
+
var DAY_MS = 864e5;
|
|
7
|
+
var DEFAULT_CHOICE = {
|
|
8
|
+
state: "granted",
|
|
9
|
+
source: "default",
|
|
10
|
+
updatedAt: null,
|
|
11
|
+
expiresAt: null
|
|
12
|
+
};
|
|
13
|
+
var changeListeners = /* @__PURE__ */ new Set();
|
|
14
|
+
function onConsentChange(listener) {
|
|
15
|
+
changeListeners.add(listener);
|
|
7
16
|
return () => {
|
|
8
|
-
|
|
17
|
+
changeListeners.delete(listener);
|
|
9
18
|
};
|
|
10
19
|
}
|
|
20
|
+
function notifyConsentChanged(choice) {
|
|
21
|
+
for (const listener of changeListeners) {
|
|
22
|
+
try {
|
|
23
|
+
listener(choice);
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
11
28
|
function buildConsentPayload(state) {
|
|
12
29
|
return {
|
|
13
30
|
ad_storage: state,
|
|
@@ -16,42 +33,88 @@ function buildConsentPayload(state) {
|
|
|
16
33
|
analytics_storage: state
|
|
17
34
|
};
|
|
18
35
|
}
|
|
19
|
-
function
|
|
20
|
-
if (typeof window === "undefined") return
|
|
36
|
+
function getConsentChoice() {
|
|
37
|
+
if (typeof window === "undefined") return DEFAULT_CHOICE;
|
|
21
38
|
try {
|
|
22
|
-
const
|
|
23
|
-
|
|
39
|
+
const stored = window.localStorage.getItem(CONSENT_STATE_KEY);
|
|
40
|
+
const updatedAt = window.localStorage.getItem(CONSENT_TIMESTAMP_KEY);
|
|
41
|
+
if (stored === "granted")
|
|
42
|
+
return { state: "granted", source: "explicit", updatedAt, expiresAt: null };
|
|
43
|
+
if (stored === "denied") {
|
|
44
|
+
let expiresAt = window.localStorage.getItem(CONSENT_EXPIRES_AT_KEY);
|
|
45
|
+
if (!expiresAt) {
|
|
46
|
+
expiresAt = new Date(Date.now() + DEFAULT_DECLINE_TTL_DAYS * DAY_MS).toISOString();
|
|
47
|
+
try {
|
|
48
|
+
window.localStorage.setItem(CONSENT_EXPIRES_AT_KEY, expiresAt);
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (!(Date.parse(expiresAt) <= Date.now()))
|
|
53
|
+
return { state: "denied", source: "explicit", updatedAt, expiresAt };
|
|
54
|
+
}
|
|
24
55
|
} catch {
|
|
25
56
|
}
|
|
26
|
-
return
|
|
57
|
+
return DEFAULT_CHOICE;
|
|
27
58
|
}
|
|
28
|
-
function
|
|
59
|
+
function getConsentState() {
|
|
60
|
+
return getConsentChoice().state;
|
|
61
|
+
}
|
|
62
|
+
function pushConsentToPlatforms(state) {
|
|
29
63
|
if (typeof window === "undefined") return;
|
|
30
|
-
try {
|
|
31
|
-
window.localStorage.setItem(CONSENT_STATE_KEY, state);
|
|
32
|
-
window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
|
|
33
|
-
} catch {
|
|
34
|
-
}
|
|
35
64
|
if (typeof window.gtag === "function")
|
|
36
65
|
window.gtag("consent", "update", buildConsentPayload(state));
|
|
37
66
|
if (typeof window.fbq === "function")
|
|
38
67
|
window.fbq("consent", state === "granted" ? "grant" : "revoke");
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
68
|
+
}
|
|
69
|
+
function setConsentState(state, options) {
|
|
70
|
+
if (typeof window === "undefined") return;
|
|
71
|
+
const requestedTtl = options?.declineTtlDays;
|
|
72
|
+
const ttlDays = typeof requestedTtl === "number" && Number.isFinite(requestedTtl) && requestedTtl > 0 ? requestedTtl : DEFAULT_DECLINE_TTL_DAYS;
|
|
73
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
74
|
+
const expiresAt = state === "denied" ? new Date(Date.now() + ttlDays * DAY_MS).toISOString() : null;
|
|
75
|
+
try {
|
|
76
|
+
window.localStorage.setItem(CONSENT_STATE_KEY, state);
|
|
77
|
+
window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, updatedAt);
|
|
78
|
+
if (expiresAt !== null) {
|
|
79
|
+
window.localStorage.setItem(CONSENT_EXPIRES_AT_KEY, expiresAt);
|
|
80
|
+
} else {
|
|
81
|
+
window.localStorage.removeItem(CONSENT_EXPIRES_AT_KEY);
|
|
45
82
|
}
|
|
83
|
+
} catch {
|
|
46
84
|
}
|
|
85
|
+
pushConsentToPlatforms(state);
|
|
86
|
+
notifyConsentChanged({ state, source: "explicit", updatedAt, expiresAt });
|
|
87
|
+
}
|
|
88
|
+
function optIn() {
|
|
89
|
+
setConsentState("granted");
|
|
90
|
+
}
|
|
91
|
+
function optOut(options) {
|
|
92
|
+
setConsentState("denied", options);
|
|
47
93
|
}
|
|
48
94
|
function resetConsent() {
|
|
49
95
|
if (typeof window === "undefined") return;
|
|
50
96
|
try {
|
|
51
97
|
window.localStorage.removeItem(CONSENT_STATE_KEY);
|
|
52
98
|
window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
|
|
99
|
+
window.localStorage.removeItem(CONSENT_EXPIRES_AT_KEY);
|
|
53
100
|
} catch {
|
|
54
101
|
}
|
|
102
|
+
pushConsentToPlatforms("granted");
|
|
103
|
+
notifyConsentChanged(DEFAULT_CHOICE);
|
|
104
|
+
}
|
|
105
|
+
function createEffectiveConsentSnippet() {
|
|
106
|
+
return `
|
|
107
|
+
var aranovaConsent = (function () {
|
|
108
|
+
try {
|
|
109
|
+
if (window.localStorage.getItem('${CONSENT_STATE_KEY}') === 'denied') {
|
|
110
|
+
var exp = window.localStorage.getItem('${CONSENT_EXPIRES_AT_KEY}');
|
|
111
|
+
var expMs = exp ? Date.parse(exp) : NaN;
|
|
112
|
+
if (!(expMs <= Date.now())) return 'denied';
|
|
113
|
+
}
|
|
114
|
+
} catch (e) {}
|
|
115
|
+
return 'granted';
|
|
116
|
+
})();
|
|
117
|
+
`.trim();
|
|
55
118
|
}
|
|
56
119
|
|
|
57
120
|
// ../tracking-core/src/tracking.ts
|
|
@@ -166,12 +229,12 @@ function createConsentDefaultScript() {
|
|
|
166
229
|
window.dataLayer = window.dataLayer || [];
|
|
167
230
|
function gtag(){dataLayer.push(arguments);}
|
|
168
231
|
window.gtag = gtag;
|
|
232
|
+
${createEffectiveConsentSnippet()}
|
|
169
233
|
gtag('consent', 'default', {
|
|
170
|
-
ad_storage:
|
|
171
|
-
ad_user_data:
|
|
172
|
-
ad_personalization:
|
|
173
|
-
analytics_storage:
|
|
174
|
-
wait_for_update: 500,
|
|
234
|
+
ad_storage: aranovaConsent,
|
|
235
|
+
ad_user_data: aranovaConsent,
|
|
236
|
+
ad_personalization: aranovaConsent,
|
|
237
|
+
analytics_storage: aranovaConsent
|
|
175
238
|
});
|
|
176
239
|
`.trim();
|
|
177
240
|
}
|
|
@@ -185,21 +248,6 @@ gtag('js', new Date());
|
|
|
185
248
|
gtag('config', '${gtagId}');
|
|
186
249
|
`.trim();
|
|
187
250
|
}
|
|
188
|
-
function createConsentRestoreScript() {
|
|
189
|
-
return `
|
|
190
|
-
try {
|
|
191
|
-
var consentState = window.localStorage.getItem('consent_state');
|
|
192
|
-
if (window.gtag && (consentState === 'granted' || consentState === 'denied')) {
|
|
193
|
-
window.gtag('consent', 'update', {
|
|
194
|
-
ad_storage: consentState,
|
|
195
|
-
ad_user_data: consentState,
|
|
196
|
-
ad_personalization: consentState,
|
|
197
|
-
analytics_storage: consentState,
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
} catch (e) {}
|
|
201
|
-
`.trim();
|
|
202
|
-
}
|
|
203
251
|
var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
|
|
204
252
|
function isValidSendTo(sendTo) {
|
|
205
253
|
return SEND_TO_RE.test(sendTo);
|
|
@@ -278,7 +326,8 @@ document,'script','${FB_EVENTS_SCRIPT_HOST}');`.trim();
|
|
|
278
326
|
}
|
|
279
327
|
function createMetaConsentDefaultScript() {
|
|
280
328
|
return `${fbqStubScript()}
|
|
281
|
-
|
|
329
|
+
${createEffectiveConsentSnippet()}
|
|
330
|
+
fbq('consent', aranovaConsent === 'denied' ? 'revoke' : 'grant');`;
|
|
282
331
|
}
|
|
283
332
|
function createMetaPixelInitScript(pixelId) {
|
|
284
333
|
if (!isValidMetaPixelId(pixelId)) return "";
|
|
@@ -291,14 +340,71 @@ function createMetaPixelInitScriptMulti(pixelIds) {
|
|
|
291
340
|
return `${inits.join("\n")}
|
|
292
341
|
fbq('track', 'PageView');`;
|
|
293
342
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
343
|
+
|
|
344
|
+
// ../tracking-core/src/landing.ts
|
|
345
|
+
var LANDING_STORAGE_KEY = "_aranova_track_landing";
|
|
346
|
+
var memoryRecord = null;
|
|
347
|
+
function sanitizeParams(value) {
|
|
348
|
+
if (typeof value !== "object" || value === null) return {};
|
|
349
|
+
const source = value;
|
|
350
|
+
return TRACKING_PARAM_KEYS.reduce((params, key) => {
|
|
351
|
+
const entry = source[key];
|
|
352
|
+
if (typeof entry === "string" && entry.length > 0) params[key] = entry;
|
|
353
|
+
return params;
|
|
354
|
+
}, {});
|
|
355
|
+
}
|
|
356
|
+
function readStoredRecord() {
|
|
357
|
+
try {
|
|
358
|
+
const raw = window.localStorage.getItem(LANDING_STORAGE_KEY);
|
|
359
|
+
if (!raw) return null;
|
|
360
|
+
const parsed = JSON.parse(raw);
|
|
361
|
+
if (typeof parsed.session_id !== "string" || parsed.session_id.length === 0) return null;
|
|
362
|
+
return { session_id: parsed.session_id, params: sanitizeParams(parsed.params) };
|
|
363
|
+
} catch {
|
|
364
|
+
return null;
|
|
300
365
|
}
|
|
301
|
-
}
|
|
366
|
+
}
|
|
367
|
+
function writeRecord(record) {
|
|
368
|
+
memoryRecord = record;
|
|
369
|
+
try {
|
|
370
|
+
window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record));
|
|
371
|
+
} catch {
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function captureFromUrl(url) {
|
|
375
|
+
try {
|
|
376
|
+
const resolved = new URL(url ?? window.location.href, window.location.origin);
|
|
377
|
+
return getTrackingQueryValues(resolved.searchParams);
|
|
378
|
+
} catch {
|
|
379
|
+
return {};
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
function getOrCaptureLandingParams(sessionId, url) {
|
|
383
|
+
if (typeof window === "undefined") return {};
|
|
384
|
+
const stored = readStoredRecord();
|
|
385
|
+
if (stored && stored.session_id === sessionId) {
|
|
386
|
+
memoryRecord = stored;
|
|
387
|
+
return stored.params;
|
|
388
|
+
}
|
|
389
|
+
if (memoryRecord && memoryRecord.session_id === sessionId) {
|
|
390
|
+
return memoryRecord.params;
|
|
391
|
+
}
|
|
392
|
+
const record = { session_id: sessionId, params: captureFromUrl(url) };
|
|
393
|
+
writeRecord(record);
|
|
394
|
+
return record.params;
|
|
395
|
+
}
|
|
396
|
+
function buildLandingPayloadFields(sessionId, override) {
|
|
397
|
+
const params = override ?? (typeof window === "undefined" ? null : getOrCaptureLandingParams(sessionId));
|
|
398
|
+
if (params === null) return {};
|
|
399
|
+
return {
|
|
400
|
+
landing_gclid: params.gclid ?? null,
|
|
401
|
+
landing_fbclid: params.fbclid ?? null,
|
|
402
|
+
landing_utm_source: params.utm_source ?? null,
|
|
403
|
+
landing_utm_medium: params.utm_medium ?? null,
|
|
404
|
+
landing_utm_campaign: params.utm_campaign ?? null,
|
|
405
|
+
landing_utm_term: params.utm_term ?? null,
|
|
406
|
+
landing_utm_content: params.utm_content ?? null
|
|
407
|
+
};
|
|
302
408
|
}
|
|
303
409
|
|
|
304
410
|
// ../tracking-core/src/payloads.ts
|
|
@@ -327,6 +433,9 @@ function createTrackingSessionUpsertPayload(trackingParams, input, context) {
|
|
|
327
433
|
utm_campaign: trackingParams.utm_campaign,
|
|
328
434
|
utm_term: trackingParams.utm_term,
|
|
329
435
|
utm_content: trackingParams.utm_content,
|
|
436
|
+
// Omitted entirely when the landing isn't observable (SSR, no override) —
|
|
437
|
+
// present-as-null would wrongly tell the backend "landed with no params".
|
|
438
|
+
...buildLandingPayloadFields(input.sessionId, input.landingParams),
|
|
330
439
|
first_page: input.firstPage ?? null,
|
|
331
440
|
consent_state: input.consentState ?? null,
|
|
332
441
|
context
|
|
@@ -348,8 +457,6 @@ function createTrackingEventCreatePayload(trackingParams, input, context) {
|
|
|
348
457
|
|
|
349
458
|
// ../tracking-core/src/resources/conversion-firing.ts
|
|
350
459
|
var DEDUP_PREFIX = "_aranova_conv_";
|
|
351
|
-
var MAX_PENDING = 100;
|
|
352
|
-
var pendingQueue = [];
|
|
353
460
|
function dedupKey(input) {
|
|
354
461
|
return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
|
|
355
462
|
}
|
|
@@ -373,23 +480,9 @@ function fireOnce(input) {
|
|
|
373
480
|
if (fireGtagConversion(input)) markFired(input);
|
|
374
481
|
}
|
|
375
482
|
function fireConversionWithConsent(input) {
|
|
376
|
-
|
|
377
|
-
if (state === "denied") return;
|
|
378
|
-
if (state === "pending") {
|
|
379
|
-
if (pendingQueue.length >= MAX_PENDING) pendingQueue.shift();
|
|
380
|
-
pendingQueue.push(input);
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
483
|
+
if (getConsentState() === "denied") return;
|
|
383
484
|
fireOnce(input);
|
|
384
485
|
}
|
|
385
|
-
function flushPendingConversions() {
|
|
386
|
-
if (getConsentState() !== "granted") return;
|
|
387
|
-
while (pendingQueue.length > 0) {
|
|
388
|
-
const input = pendingQueue.shift();
|
|
389
|
-
if (input) fireOnce(input);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
if (typeof window !== "undefined") onConsentGranted(flushPendingConversions);
|
|
393
486
|
|
|
394
487
|
// ../tracking-core/src/resources/conversion-config.ts
|
|
395
488
|
function isStringMap(value) {
|
|
@@ -897,7 +990,13 @@ function readTrackingParams() {
|
|
|
897
990
|
}
|
|
898
991
|
function consentSnapshot() {
|
|
899
992
|
try {
|
|
900
|
-
|
|
993
|
+
const choice = getConsentChoice();
|
|
994
|
+
return {
|
|
995
|
+
state: choice.state,
|
|
996
|
+
source: choice.source,
|
|
997
|
+
updated_at: choice.updatedAt,
|
|
998
|
+
expires_at: choice.expiresAt
|
|
999
|
+
};
|
|
901
1000
|
} catch {
|
|
902
1001
|
return null;
|
|
903
1002
|
}
|
|
@@ -970,6 +1069,7 @@ function createTrackingClient(config) {
|
|
|
970
1069
|
initialParams = captureTrackingParamsFromLocation();
|
|
971
1070
|
} catch {
|
|
972
1071
|
}
|
|
1072
|
+
getOrCaptureLandingParams(sessionId);
|
|
973
1073
|
try {
|
|
974
1074
|
captureFbc();
|
|
975
1075
|
} catch {
|
|
@@ -1019,6 +1119,11 @@ function createTrackingClient(config) {
|
|
|
1019
1119
|
utm_campaign: params.utm_campaign,
|
|
1020
1120
|
utm_term: params.utm_term,
|
|
1021
1121
|
utm_content: params.utm_content,
|
|
1122
|
+
// Landing params for the CURRENT session id — captured on the spot when
|
|
1123
|
+
// the session just rotated (the current URL is the rotated session's
|
|
1124
|
+
// landing), reused from the stored record otherwise. Keys are omitted
|
|
1125
|
+
// entirely when the landing isn't observable (SSR).
|
|
1126
|
+
...buildLandingPayloadFields(sessionId),
|
|
1022
1127
|
first_page: firstPage,
|
|
1023
1128
|
consent_state: consentSnapshot(),
|
|
1024
1129
|
context
|
|
@@ -1086,6 +1191,7 @@ function createTrackingClient(config) {
|
|
|
1086
1191
|
return {
|
|
1087
1192
|
trackEvent,
|
|
1088
1193
|
flush,
|
|
1194
|
+
flushBeacon: flushOnUnload,
|
|
1089
1195
|
getSessionId: () => sessionId,
|
|
1090
1196
|
getVisitorId: () => visitorId,
|
|
1091
1197
|
destroy: () => {
|
|
@@ -1110,9 +1216,17 @@ var ctaClickMetadataSchema = z2.object({
|
|
|
1110
1216
|
path: z2.string()
|
|
1111
1217
|
}).strict(),
|
|
1112
1218
|
section: z2.string().nullable().optional(),
|
|
1113
|
-
destination_url: z2.string().nullable().optional()
|
|
1219
|
+
destination_url: z2.string().nullable().optional(),
|
|
1220
|
+
// Set by auto-capture (and available to manual callers): the link target
|
|
1221
|
+
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
1222
|
+
href: z2.string().nullable().optional(),
|
|
1223
|
+
element: z2.string().nullable().optional()
|
|
1224
|
+
}).strict();
|
|
1225
|
+
var ctaClickConfigSchema = z2.object({
|
|
1226
|
+
autoCapture: z2.object({
|
|
1227
|
+
selector: z2.string().optional()
|
|
1228
|
+
}).strict().optional()
|
|
1114
1229
|
}).strict();
|
|
1115
|
-
var ctaClickConfigSchema = z2.object({}).strict();
|
|
1116
1230
|
|
|
1117
1231
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
1118
1232
|
import { z as z3 } from "zod";
|
|
@@ -1188,31 +1302,44 @@ var multiPageSessionConfigSchema = z6.object({
|
|
|
1188
1302
|
pageThreshold: z6.number().int().min(2)
|
|
1189
1303
|
}).strict();
|
|
1190
1304
|
|
|
1191
|
-
// ../tracking-core/src/events/
|
|
1305
|
+
// ../tracking-core/src/events/page-exit.ts
|
|
1192
1306
|
import { z as z7 } from "zod";
|
|
1193
|
-
var
|
|
1194
|
-
|
|
1307
|
+
var pageExitMetadataSchema = z7.object({
|
|
1308
|
+
dwell_ms: z7.number().int().min(0),
|
|
1309
|
+
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
1310
|
+
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
1311
|
+
max_scroll_percent: z7.number().int().min(0).max(100).nullable(),
|
|
1195
1312
|
page: z7.object({
|
|
1196
1313
|
path: z7.string()
|
|
1197
|
-
}).strict()
|
|
1198
|
-
section: z7.string().nullable().optional()
|
|
1314
|
+
}).strict()
|
|
1199
1315
|
}).strict();
|
|
1200
|
-
var
|
|
1316
|
+
var pageExitConfigSchema = z7.object({}).strict();
|
|
1201
1317
|
|
|
1202
|
-
// ../tracking-core/src/events/
|
|
1318
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
1203
1319
|
import { z as z8 } from "zod";
|
|
1204
|
-
var
|
|
1205
|
-
|
|
1320
|
+
var phoneClickMetadataSchema = z8.object({
|
|
1321
|
+
phone_number: z8.string(),
|
|
1206
1322
|
page: z8.object({
|
|
1207
1323
|
path: z8.string()
|
|
1324
|
+
}).strict(),
|
|
1325
|
+
section: z8.string().nullable().optional()
|
|
1326
|
+
}).strict();
|
|
1327
|
+
var phoneClickConfigSchema = z8.object({}).strict();
|
|
1328
|
+
|
|
1329
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
1330
|
+
import { z as z9 } from "zod";
|
|
1331
|
+
var scrollDepthMetadataSchema = z9.object({
|
|
1332
|
+
depth_percent: z9.number().int().min(1).max(100),
|
|
1333
|
+
page: z9.object({
|
|
1334
|
+
path: z9.string()
|
|
1208
1335
|
}).strict()
|
|
1209
1336
|
}).strict();
|
|
1210
|
-
var scrollDepthConfigSchema =
|
|
1211
|
-
thresholds:
|
|
1337
|
+
var scrollDepthConfigSchema = z9.object({
|
|
1338
|
+
thresholds: z9.array(z9.number().int().min(1).max(100)).min(1)
|
|
1212
1339
|
}).strict();
|
|
1213
1340
|
|
|
1214
1341
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
1215
|
-
import { z as
|
|
1342
|
+
import { z as z10 } from "zod";
|
|
1216
1343
|
var SPECIFIC_PAGE_NAMES = [
|
|
1217
1344
|
"contact_page",
|
|
1218
1345
|
"about_page",
|
|
@@ -1223,18 +1350,18 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
1223
1350
|
"faq_page",
|
|
1224
1351
|
"testimonials_page"
|
|
1225
1352
|
];
|
|
1226
|
-
var specificPageNameSchema =
|
|
1227
|
-
var specificPageVisitMetadataSchema =
|
|
1353
|
+
var specificPageNameSchema = z10.enum(SPECIFIC_PAGE_NAMES);
|
|
1354
|
+
var specificPageVisitMetadataSchema = z10.object({
|
|
1228
1355
|
page_name: specificPageNameSchema,
|
|
1229
|
-
page:
|
|
1230
|
-
path:
|
|
1356
|
+
page: z10.object({
|
|
1357
|
+
path: z10.string()
|
|
1231
1358
|
}).strict()
|
|
1232
1359
|
}).strict();
|
|
1233
|
-
var specificPageVisitConfigSchema =
|
|
1234
|
-
pages:
|
|
1235
|
-
|
|
1360
|
+
var specificPageVisitConfigSchema = z10.object({
|
|
1361
|
+
pages: z10.array(
|
|
1362
|
+
z10.object({
|
|
1236
1363
|
name: specificPageNameSchema,
|
|
1237
|
-
pathPattern:
|
|
1364
|
+
pathPattern: z10.custom((value) => value instanceof RegExp, {
|
|
1238
1365
|
message: "pathPattern must be a RegExp"
|
|
1239
1366
|
})
|
|
1240
1367
|
}).strict()
|
|
@@ -1242,15 +1369,15 @@ var specificPageVisitConfigSchema = z9.object({
|
|
|
1242
1369
|
}).strict();
|
|
1243
1370
|
|
|
1244
1371
|
// ../tracking-core/src/events/time-on-site.ts
|
|
1245
|
-
import { z as
|
|
1246
|
-
var timeOnSiteMetadataSchema =
|
|
1247
|
-
duration_ms:
|
|
1248
|
-
page:
|
|
1249
|
-
path:
|
|
1372
|
+
import { z as z11 } from "zod";
|
|
1373
|
+
var timeOnSiteMetadataSchema = z11.object({
|
|
1374
|
+
duration_ms: z11.number().int().nonnegative(),
|
|
1375
|
+
page: z11.object({
|
|
1376
|
+
path: z11.string()
|
|
1250
1377
|
}).strict()
|
|
1251
1378
|
}).strict();
|
|
1252
|
-
var timeOnSiteConfigSchema =
|
|
1253
|
-
thresholdSeconds:
|
|
1379
|
+
var timeOnSiteConfigSchema = z11.object({
|
|
1380
|
+
thresholdSeconds: z11.number().int().positive()
|
|
1254
1381
|
}).strict();
|
|
1255
1382
|
|
|
1256
1383
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -1292,6 +1419,11 @@ var EVENT_REGISTRY = {
|
|
|
1292
1419
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
1293
1420
|
configSchema: sdkHeartbeatConfigSchema
|
|
1294
1421
|
},
|
|
1422
|
+
page_exit: {
|
|
1423
|
+
kind: "automatic",
|
|
1424
|
+
metadataSchema: pageExitMetadataSchema,
|
|
1425
|
+
configSchema: pageExitConfigSchema
|
|
1426
|
+
},
|
|
1295
1427
|
// --- manual triggers ---
|
|
1296
1428
|
form_submit: {
|
|
1297
1429
|
kind: "manual",
|
|
@@ -1535,6 +1667,163 @@ function attachFormStart(client, config) {
|
|
|
1535
1667
|
};
|
|
1536
1668
|
}
|
|
1537
1669
|
|
|
1670
|
+
// ../tracking-core/src/triggers/page-exit.ts
|
|
1671
|
+
function attachPageExit(client) {
|
|
1672
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1673
|
+
return () => {
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
let currentPath2 = window.location.pathname;
|
|
1677
|
+
let activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1678
|
+
let accumulatedMs = 0;
|
|
1679
|
+
let maxScrollPercent = null;
|
|
1680
|
+
let rafId = null;
|
|
1681
|
+
function getScrollPercent() {
|
|
1682
|
+
const doc = document.documentElement;
|
|
1683
|
+
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1684
|
+
const scrollHeight = doc.scrollHeight;
|
|
1685
|
+
const clientHeight = doc.clientHeight;
|
|
1686
|
+
if (scrollHeight <= clientHeight) return 100;
|
|
1687
|
+
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1688
|
+
}
|
|
1689
|
+
function onScroll() {
|
|
1690
|
+
if (rafId !== null) return;
|
|
1691
|
+
rafId = requestAnimationFrame(() => {
|
|
1692
|
+
rafId = null;
|
|
1693
|
+
const percent = getScrollPercent();
|
|
1694
|
+
if (percent >= 1 && (maxScrollPercent === null || percent > maxScrollPercent)) {
|
|
1695
|
+
maxScrollPercent = Math.min(percent, 100);
|
|
1696
|
+
}
|
|
1697
|
+
});
|
|
1698
|
+
}
|
|
1699
|
+
function settledDwellMs() {
|
|
1700
|
+
let total = accumulatedMs;
|
|
1701
|
+
if (activeSince !== null) {
|
|
1702
|
+
total += Date.now() - activeSince;
|
|
1703
|
+
}
|
|
1704
|
+
return Math.max(0, Math.round(total));
|
|
1705
|
+
}
|
|
1706
|
+
function emitSegment(path, flush) {
|
|
1707
|
+
const dwell = settledDwellMs();
|
|
1708
|
+
if (dwell === 0) return;
|
|
1709
|
+
client.trackEvent({
|
|
1710
|
+
eventType: "page_exit",
|
|
1711
|
+
metadata: {
|
|
1712
|
+
dwell_ms: dwell,
|
|
1713
|
+
max_scroll_percent: maxScrollPercent,
|
|
1714
|
+
page: { path }
|
|
1715
|
+
},
|
|
1716
|
+
pageUrl: window.location.href,
|
|
1717
|
+
occurredAt: null
|
|
1718
|
+
});
|
|
1719
|
+
if (flush) {
|
|
1720
|
+
client.flushBeacon();
|
|
1721
|
+
}
|
|
1722
|
+
accumulatedMs = 0;
|
|
1723
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1724
|
+
}
|
|
1725
|
+
function onNavigate() {
|
|
1726
|
+
const newPath = window.location.pathname;
|
|
1727
|
+
if (newPath === currentPath2) return;
|
|
1728
|
+
emitSegment(currentPath2, false);
|
|
1729
|
+
currentPath2 = newPath;
|
|
1730
|
+
maxScrollPercent = null;
|
|
1731
|
+
accumulatedMs = 0;
|
|
1732
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1733
|
+
}
|
|
1734
|
+
function onVisibilityChange() {
|
|
1735
|
+
if (document.visibilityState === "hidden") {
|
|
1736
|
+
emitSegment(currentPath2, true);
|
|
1737
|
+
} else {
|
|
1738
|
+
activeSince = Date.now();
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
function onPageHide() {
|
|
1742
|
+
emitSegment(currentPath2, true);
|
|
1743
|
+
}
|
|
1744
|
+
const originalPushState = history.pushState.bind(history);
|
|
1745
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
1746
|
+
function patchedPushState(...args) {
|
|
1747
|
+
originalPushState(...args);
|
|
1748
|
+
setTimeout(onNavigate, 0);
|
|
1749
|
+
}
|
|
1750
|
+
function patchedReplaceState(...args) {
|
|
1751
|
+
originalReplaceState(...args);
|
|
1752
|
+
setTimeout(onNavigate, 0);
|
|
1753
|
+
}
|
|
1754
|
+
history.pushState = patchedPushState;
|
|
1755
|
+
history.replaceState = patchedReplaceState;
|
|
1756
|
+
window.addEventListener("popstate", onNavigate);
|
|
1757
|
+
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1758
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1759
|
+
window.addEventListener("pagehide", onPageHide);
|
|
1760
|
+
return () => {
|
|
1761
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1762
|
+
history.pushState = originalPushState;
|
|
1763
|
+
history.replaceState = originalReplaceState;
|
|
1764
|
+
window.removeEventListener("popstate", onNavigate);
|
|
1765
|
+
window.removeEventListener("scroll", onScroll);
|
|
1766
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1767
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
// ../tracking-core/src/triggers/cta-click-capture.ts
|
|
1772
|
+
var DEFAULT_CTA_SELECTOR = "[data-aranova-cta]";
|
|
1773
|
+
var CTA_NAME_MAX_LENGTH = 120;
|
|
1774
|
+
function describeElement(el) {
|
|
1775
|
+
const tag = el.tagName.toLowerCase();
|
|
1776
|
+
return el.id ? `${tag}#${el.id}` : tag;
|
|
1777
|
+
}
|
|
1778
|
+
function resolveCtaName(el) {
|
|
1779
|
+
const explicit = el.getAttribute("data-aranova-cta");
|
|
1780
|
+
if (explicit && explicit.trim().length > 0) return explicit.trim();
|
|
1781
|
+
const text = (el.textContent ?? "").trim().replace(/\s+/g, " ");
|
|
1782
|
+
if (text.length > 0) return text.slice(0, CTA_NAME_MAX_LENGTH);
|
|
1783
|
+
return describeElement(el);
|
|
1784
|
+
}
|
|
1785
|
+
function attachCtaClickCapture(client, config) {
|
|
1786
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1787
|
+
return () => {
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
const autoCapture = config.autoCapture;
|
|
1791
|
+
if (!autoCapture) {
|
|
1792
|
+
return () => {
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
const selector = autoCapture.selector ?? DEFAULT_CTA_SELECTOR;
|
|
1796
|
+
function onClick(event) {
|
|
1797
|
+
const target = event.target;
|
|
1798
|
+
if (!(target instanceof Element)) return;
|
|
1799
|
+
let matched = null;
|
|
1800
|
+
try {
|
|
1801
|
+
matched = target.closest(selector);
|
|
1802
|
+
} catch {
|
|
1803
|
+
return;
|
|
1804
|
+
}
|
|
1805
|
+
if (matched === null) return;
|
|
1806
|
+
const href = matched instanceof HTMLAnchorElement ? matched.href || null : matched.getAttribute("href");
|
|
1807
|
+
client.trackEvent({
|
|
1808
|
+
eventType: "cta_click",
|
|
1809
|
+
metadata: {
|
|
1810
|
+
cta_name: resolveCtaName(matched),
|
|
1811
|
+
page: { path: window.location.pathname },
|
|
1812
|
+
section: matched.getAttribute("data-aranova-section"),
|
|
1813
|
+
destination_url: href,
|
|
1814
|
+
href,
|
|
1815
|
+
element: describeElement(matched)
|
|
1816
|
+
},
|
|
1817
|
+
pageUrl: window.location.href,
|
|
1818
|
+
occurredAt: null
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1821
|
+
document.addEventListener("click", onClick, true);
|
|
1822
|
+
return () => {
|
|
1823
|
+
document.removeEventListener("click", onClick, true);
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1538
1827
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
1539
1828
|
var AranovaApiError = class extends Error {
|
|
1540
1829
|
constructor(message, options) {
|
|
@@ -1741,42 +2030,42 @@ function createSalesClient(config) {
|
|
|
1741
2030
|
}
|
|
1742
2031
|
|
|
1743
2032
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
1744
|
-
import { z as
|
|
2033
|
+
import { z as z12 } from "zod";
|
|
1745
2034
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
1746
2035
|
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
1747
|
-
var currencySchema =
|
|
1748
|
-
var centsSchema =
|
|
1749
|
-
var quantitySchema =
|
|
1750
|
-
var metadataSchema =
|
|
1751
|
-
var saleItemSchema =
|
|
1752
|
-
external_item_id:
|
|
1753
|
-
name:
|
|
1754
|
-
category:
|
|
2036
|
+
var currencySchema = z12.enum(SUPPORTED_CURRENCIES);
|
|
2037
|
+
var centsSchema = z12.number().int().nonnegative();
|
|
2038
|
+
var quantitySchema = z12.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
2039
|
+
var metadataSchema = z12.record(z12.unknown());
|
|
2040
|
+
var saleItemSchema = z12.object({
|
|
2041
|
+
external_item_id: z12.string().nullable().optional(),
|
|
2042
|
+
name: z12.string().nullable().optional(),
|
|
2043
|
+
category: z12.string().nullable().optional(),
|
|
1755
2044
|
quantity: quantitySchema,
|
|
1756
2045
|
unit_price_cents: centsSchema,
|
|
1757
2046
|
// Non-negativity validated on the wire — same contract as the other cents
|
|
1758
2047
|
// fields — and backstopped by the DB CHECK.
|
|
1759
2048
|
unit_cost_cents: centsSchema.nullable().optional()
|
|
1760
2049
|
}).strict();
|
|
1761
|
-
var saleServiceSchema =
|
|
1762
|
-
service:
|
|
2050
|
+
var saleServiceSchema = z12.object({
|
|
2051
|
+
service: z12.string(),
|
|
1763
2052
|
amount_cents: centsSchema
|
|
1764
2053
|
}).strict();
|
|
1765
|
-
var customerNameSchema =
|
|
1766
|
-
var customerPhoneSchema =
|
|
1767
|
-
var customerEmailSchema =
|
|
2054
|
+
var customerNameSchema = z12.string().max(200);
|
|
2055
|
+
var customerPhoneSchema = z12.string().max(64);
|
|
2056
|
+
var customerEmailSchema = z12.string().max(320).email();
|
|
1768
2057
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
1769
2058
|
if (val.services != null) {
|
|
1770
2059
|
if (val.service != null) {
|
|
1771
2060
|
ctx.addIssue({
|
|
1772
|
-
code:
|
|
2061
|
+
code: z12.ZodIssueCode.custom,
|
|
1773
2062
|
message: "pass either `service` or `services`, not both",
|
|
1774
2063
|
path: ["services"]
|
|
1775
2064
|
});
|
|
1776
2065
|
}
|
|
1777
2066
|
if (val.services.length === 0) {
|
|
1778
2067
|
ctx.addIssue({
|
|
1779
|
-
code:
|
|
2068
|
+
code: z12.ZodIssueCode.custom,
|
|
1780
2069
|
message: "`services` must not be empty",
|
|
1781
2070
|
path: ["services"]
|
|
1782
2071
|
});
|
|
@@ -1784,7 +2073,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1784
2073
|
const keys = val.services.map((s) => s.service);
|
|
1785
2074
|
if (new Set(keys).size !== keys.length) {
|
|
1786
2075
|
ctx.addIssue({
|
|
1787
|
-
code:
|
|
2076
|
+
code: z12.ZodIssueCode.custom,
|
|
1788
2077
|
message: "`services` must not list the same service more than once",
|
|
1789
2078
|
path: ["services"]
|
|
1790
2079
|
});
|
|
@@ -1793,7 +2082,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1793
2082
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
1794
2083
|
if (val.amount_total_cents !== sum) {
|
|
1795
2084
|
ctx.addIssue({
|
|
1796
|
-
code:
|
|
2085
|
+
code: z12.ZodIssueCode.custom,
|
|
1797
2086
|
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
1798
2087
|
path: ["amount_total_cents"]
|
|
1799
2088
|
});
|
|
@@ -1801,37 +2090,37 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1801
2090
|
}
|
|
1802
2091
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
1803
2092
|
ctx.addIssue({
|
|
1804
|
-
code:
|
|
2093
|
+
code: z12.ZodIssueCode.custom,
|
|
1805
2094
|
message: "amount_total_cents is required unless `services` is provided",
|
|
1806
2095
|
path: ["amount_total_cents"]
|
|
1807
2096
|
});
|
|
1808
2097
|
}
|
|
1809
2098
|
}
|
|
1810
|
-
var saleCreateSchema =
|
|
1811
|
-
external_id:
|
|
1812
|
-
description:
|
|
1813
|
-
service:
|
|
1814
|
-
services:
|
|
2099
|
+
var saleCreateSchema = z12.object({
|
|
2100
|
+
external_id: z12.string().nullable().optional(),
|
|
2101
|
+
description: z12.string().nullable().optional(),
|
|
2102
|
+
service: z12.string().nullable().optional(),
|
|
2103
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
1815
2104
|
currency: currencySchema,
|
|
1816
2105
|
// Optional only because the plural `services` form derives it from the sum
|
|
1817
2106
|
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
1818
2107
|
amount_total_cents: centsSchema.nullable().optional(),
|
|
1819
|
-
occurred_at:
|
|
1820
|
-
environment:
|
|
1821
|
-
items:
|
|
2108
|
+
occurred_at: z12.string().datetime(),
|
|
2109
|
+
environment: z12.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
2110
|
+
items: z12.array(saleItemSchema).default([]),
|
|
1822
2111
|
metadata: metadataSchema.nullable().optional(),
|
|
1823
2112
|
customer_name: customerNameSchema.nullable().optional(),
|
|
1824
2113
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
1825
2114
|
customer_email: customerEmailSchema.nullable().optional()
|
|
1826
2115
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
1827
|
-
var saleUpdateSchema =
|
|
1828
|
-
description:
|
|
1829
|
-
service:
|
|
1830
|
-
services:
|
|
2116
|
+
var saleUpdateSchema = z12.object({
|
|
2117
|
+
description: z12.string().nullable().optional(),
|
|
2118
|
+
service: z12.string().nullable().optional(),
|
|
2119
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
1831
2120
|
currency: currencySchema.optional(),
|
|
1832
2121
|
amount_total_cents: centsSchema.optional(),
|
|
1833
|
-
occurred_at:
|
|
1834
|
-
items:
|
|
2122
|
+
occurred_at: z12.string().datetime().optional(),
|
|
2123
|
+
items: z12.array(saleItemSchema).optional(),
|
|
1835
2124
|
metadata: metadataSchema.nullable().optional(),
|
|
1836
2125
|
customer_name: customerNameSchema.nullable().optional(),
|
|
1837
2126
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
@@ -1921,36 +2210,68 @@ function useTrackingParams() {
|
|
|
1921
2210
|
}, []);
|
|
1922
2211
|
return trackingParams;
|
|
1923
2212
|
}
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
2213
|
+
var DEFAULT_CHOICE2 = {
|
|
2214
|
+
state: "granted",
|
|
2215
|
+
source: "default",
|
|
2216
|
+
updatedAt: null,
|
|
2217
|
+
expiresAt: null
|
|
2218
|
+
};
|
|
2219
|
+
function useCookiePreferences(options) {
|
|
2220
|
+
const [choice, setChoice] = useState(DEFAULT_CHOICE2);
|
|
2221
|
+
const ttlDays = options?.declineTtlDays;
|
|
1929
2222
|
useEffect(() => {
|
|
1930
|
-
|
|
2223
|
+
const sync = () => setChoice(getConsentChoice());
|
|
2224
|
+
sync();
|
|
1931
2225
|
const handleStorage = (event) => {
|
|
1932
|
-
if (event.key === CONSENT_STATE_KEY
|
|
2226
|
+
if (event.key === null || event.key === CONSENT_STATE_KEY || event.key === CONSENT_EXPIRES_AT_KEY || event.key === CONSENT_TIMESTAMP_KEY)
|
|
2227
|
+
sync();
|
|
1933
2228
|
};
|
|
1934
2229
|
window.addEventListener("storage", handleStorage);
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
2230
|
+
const unsubscribe = onConsentChange(sync);
|
|
2231
|
+
return () => {
|
|
2232
|
+
window.removeEventListener("storage", handleStorage);
|
|
2233
|
+
unsubscribe();
|
|
2234
|
+
};
|
|
1940
2235
|
}, []);
|
|
1941
|
-
const
|
|
1942
|
-
|
|
1943
|
-
|
|
2236
|
+
const optOutAction = useCallback(() => {
|
|
2237
|
+
optOut(ttlDays != null ? { declineTtlDays: ttlDays } : void 0);
|
|
2238
|
+
}, [ttlDays]);
|
|
2239
|
+
const optInAction = useCallback(() => {
|
|
2240
|
+
optIn();
|
|
1944
2241
|
}, []);
|
|
1945
2242
|
const reset = useCallback(() => {
|
|
1946
2243
|
resetConsent();
|
|
1947
|
-
setState("pending");
|
|
1948
2244
|
}, []);
|
|
2245
|
+
return {
|
|
2246
|
+
state: choice.state,
|
|
2247
|
+
source: choice.source,
|
|
2248
|
+
isDefault: choice.source === "default",
|
|
2249
|
+
isGranted: choice.state === "granted",
|
|
2250
|
+
isDenied: choice.state === "denied",
|
|
2251
|
+
updatedAt: choice.updatedAt,
|
|
2252
|
+
expiresAt: choice.expiresAt,
|
|
2253
|
+
optOut: optOutAction,
|
|
2254
|
+
optIn: optInAction,
|
|
2255
|
+
reset
|
|
2256
|
+
};
|
|
2257
|
+
}
|
|
2258
|
+
function useConsentState() {
|
|
2259
|
+
return useConsent().state;
|
|
2260
|
+
}
|
|
2261
|
+
function useConsent() {
|
|
2262
|
+
const {
|
|
2263
|
+
state,
|
|
2264
|
+
isGranted,
|
|
2265
|
+
isDenied,
|
|
2266
|
+
optIn: accept,
|
|
2267
|
+
optOut: decline,
|
|
2268
|
+
reset
|
|
2269
|
+
} = useCookiePreferences();
|
|
1949
2270
|
return {
|
|
1950
2271
|
state,
|
|
1951
|
-
isPending:
|
|
1952
|
-
isGranted
|
|
1953
|
-
isDenied
|
|
2272
|
+
isPending: false,
|
|
2273
|
+
isGranted,
|
|
2274
|
+
isDenied,
|
|
1954
2275
|
accept,
|
|
1955
2276
|
decline,
|
|
1956
2277
|
reset
|
|
@@ -2166,13 +2487,11 @@ function AdPlatformTracking({
|
|
|
2166
2487
|
strategy: "afterInteractive"
|
|
2167
2488
|
}
|
|
2168
2489
|
),
|
|
2169
|
-
/* @__PURE__ */ jsx2(Script, { id: "gtag-init", strategy: "afterInteractive", children: gtagInitScript })
|
|
2170
|
-
/* @__PURE__ */ jsx2(Script, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
|
|
2490
|
+
/* @__PURE__ */ jsx2(Script, { id: "gtag-init", strategy: "afterInteractive", children: gtagInitScript })
|
|
2171
2491
|
] }) : null,
|
|
2172
2492
|
metaAll.length > 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2173
2493
|
/* @__PURE__ */ jsx2(Script, { id: "meta-pixel-base", strategy: "afterInteractive", children: createMetaConsentDefaultScript() }),
|
|
2174
|
-
/* @__PURE__ */ jsx2(Script, { id: "meta-pixel-init", strategy: "afterInteractive", children: metaInitScript })
|
|
2175
|
-
/* @__PURE__ */ jsx2(Script, { id: "meta-pixel-consent-restore", strategy: "afterInteractive", children: createMetaConsentRestoreScript() })
|
|
2494
|
+
/* @__PURE__ */ jsx2(Script, { id: "meta-pixel-init", strategy: "afterInteractive", children: metaInitScript })
|
|
2176
2495
|
] }) : null
|
|
2177
2496
|
] });
|
|
2178
2497
|
}
|
|
@@ -2195,8 +2514,7 @@ function GoogleAdsTracking(props) {
|
|
|
2195
2514
|
strategy: "afterInteractive"
|
|
2196
2515
|
}
|
|
2197
2516
|
),
|
|
2198
|
-
/* @__PURE__ */ jsx3(Script2, { id: "gtag-init", strategy: "afterInteractive", children: initScript })
|
|
2199
|
-
/* @__PURE__ */ jsx3(Script2, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
|
|
2517
|
+
/* @__PURE__ */ jsx3(Script2, { id: "gtag-init", strategy: "afterInteractive", children: initScript })
|
|
2200
2518
|
] });
|
|
2201
2519
|
}
|
|
2202
2520
|
|
|
@@ -2204,7 +2522,7 @@ function GoogleAdsTracking(props) {
|
|
|
2204
2522
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
2205
2523
|
|
|
2206
2524
|
// package.json
|
|
2207
|
-
var version = "0.
|
|
2525
|
+
var version = "0.16.0";
|
|
2208
2526
|
|
|
2209
2527
|
// src/factory.tsx
|
|
2210
2528
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo2, useRef } from "react";
|
|
@@ -2492,6 +2810,7 @@ function createTracking(options) {
|
|
|
2492
2810
|
debug
|
|
2493
2811
|
});
|
|
2494
2812
|
const detectorClient = wrapClient(rawClient);
|
|
2813
|
+
detachers.push(attachPageExit(detectorClient));
|
|
2495
2814
|
const scrollDepth = triggers.automatic.scroll_depth;
|
|
2496
2815
|
if (scrollDepth) {
|
|
2497
2816
|
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
@@ -2500,6 +2819,10 @@ function createTracking(options) {
|
|
|
2500
2819
|
if (formStart) {
|
|
2501
2820
|
detachers.push(attachFormStart(detectorClient, formStart));
|
|
2502
2821
|
}
|
|
2822
|
+
const ctaClick = triggers.manual?.cta_click;
|
|
2823
|
+
if (ctaClick) {
|
|
2824
|
+
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2825
|
+
}
|
|
2503
2826
|
return () => {
|
|
2504
2827
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2505
2828
|
detachers[i]();
|
|
@@ -2523,6 +2846,7 @@ export {
|
|
|
2523
2846
|
AdPlatformTracking,
|
|
2524
2847
|
AranovaApiError,
|
|
2525
2848
|
ConsentBanner,
|
|
2849
|
+
DEFAULT_DECLINE_TTL_DAYS,
|
|
2526
2850
|
DEFAULT_PHONE_COUNTRY,
|
|
2527
2851
|
GoogleAdsTracking,
|
|
2528
2852
|
NAMED_RANGES,
|
|
@@ -2542,7 +2866,11 @@ export {
|
|
|
2542
2866
|
formatPhone,
|
|
2543
2867
|
formatPhoneAsTyped,
|
|
2544
2868
|
fromMinor,
|
|
2869
|
+
getConsentChoice,
|
|
2545
2870
|
getConsentState,
|
|
2871
|
+
onConsentChange,
|
|
2872
|
+
optIn,
|
|
2873
|
+
optOut,
|
|
2546
2874
|
parsePhone,
|
|
2547
2875
|
phoneField,
|
|
2548
2876
|
resetConsent,
|
|
@@ -2557,6 +2885,7 @@ export {
|
|
|
2557
2885
|
toMinor,
|
|
2558
2886
|
useConsent,
|
|
2559
2887
|
useConsentState,
|
|
2888
|
+
useCookiePreferences,
|
|
2560
2889
|
useGclid,
|
|
2561
2890
|
usePhoneConfig,
|
|
2562
2891
|
usePhoneField,
|