@aranova/tracking-react 0.12.2 → 0.14.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/dist/index.mjs CHANGED
@@ -7,6 +7,13 @@ 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 grantedListeners = /* @__PURE__ */ new Set();
11
+ function onConsentGranted(listener) {
12
+ grantedListeners.add(listener);
13
+ return () => {
14
+ grantedListeners.delete(listener);
15
+ };
16
+ }
10
17
  function buildConsentPayload(state) {
11
18
  return {
12
19
  ad_storage: state,
@@ -17,21 +24,40 @@ function buildConsentPayload(state) {
17
24
  }
18
25
  function getConsentState() {
19
26
  if (typeof window === "undefined") return "pending";
20
- const storedState = window.localStorage.getItem(CONSENT_STATE_KEY);
21
- if (storedState === "granted" || storedState === "denied") return storedState;
27
+ try {
28
+ const storedState = window.localStorage.getItem(CONSENT_STATE_KEY);
29
+ if (storedState === "granted" || storedState === "denied") return storedState;
30
+ } catch {
31
+ }
22
32
  return "pending";
23
33
  }
24
34
  function setConsentState(state) {
25
35
  if (typeof window === "undefined") return;
26
- window.localStorage.setItem(CONSENT_STATE_KEY, state);
27
- window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
36
+ try {
37
+ window.localStorage.setItem(CONSENT_STATE_KEY, state);
38
+ window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
39
+ } catch {
40
+ }
28
41
  if (typeof window.gtag === "function")
29
42
  window.gtag("consent", "update", buildConsentPayload(state));
43
+ if (typeof window.fbq === "function")
44
+ window.fbq("consent", state === "granted" ? "grant" : "revoke");
45
+ if (state === "granted") {
46
+ for (const listener of grantedListeners) {
47
+ try {
48
+ listener();
49
+ } catch {
50
+ }
51
+ }
52
+ }
30
53
  }
31
54
  function resetConsent() {
32
55
  if (typeof window === "undefined") return;
33
- window.localStorage.removeItem(CONSENT_STATE_KEY);
34
- window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
56
+ try {
57
+ window.localStorage.removeItem(CONSENT_STATE_KEY);
58
+ window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
59
+ } catch {
60
+ }
35
61
  }
36
62
  function restoreStoredConsent() {
37
63
  const consentState = getConsentState();
@@ -39,45 +65,106 @@ function restoreStoredConsent() {
39
65
  return consentState;
40
66
  }
41
67
 
42
- // ../tracking-core/src/payloads.ts
43
- function createTrackingClientContext(surface, input = {}) {
68
+ // ../tracking-core/src/tracking.ts
69
+ var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
70
+ var TRACKING_PARAM_KEYS = [
71
+ "gclid",
72
+ "fbclid",
73
+ "utm_source",
74
+ "utm_medium",
75
+ "utm_campaign",
76
+ "utm_term",
77
+ "utm_content"
78
+ ];
79
+ function createEmptyTrackingParams() {
44
80
  return {
45
- surface,
46
- sdk_version: input.sdkVersion ?? null,
47
- package_name: input.packageName ?? null,
48
- site_origin: input.siteOrigin ?? (typeof window === "undefined" ? null : window.location.origin),
49
- page_title: input.pageTitle ?? (typeof document === "undefined" ? null : document.title || null),
50
- referrer: input.referrer ?? (typeof document === "undefined" ? null : document.referrer || null),
51
- environment: input.environment ?? "production",
52
- active_gtag_ids: input.activeGtagIds ?? null
81
+ gclid: null,
82
+ fbclid: null,
83
+ utm_source: null,
84
+ utm_medium: null,
85
+ utm_campaign: null,
86
+ utm_term: null,
87
+ utm_content: null
53
88
  };
54
89
  }
55
- function createTrackingSessionUpsertPayload(trackingParams, input, context) {
56
- return {
57
- session_id: input.sessionId,
58
- visitor_id: input.visitorId ?? null,
59
- gclid: trackingParams.gclid,
60
- fbclid: trackingParams.fbclid,
61
- utm_source: trackingParams.utm_source,
62
- utm_medium: trackingParams.utm_medium,
63
- utm_campaign: trackingParams.utm_campaign,
64
- utm_term: trackingParams.utm_term,
65
- utm_content: trackingParams.utm_content,
66
- first_page: input.firstPage ?? null,
67
- consent_state: input.consentState ?? null,
68
- context
69
- };
90
+ function normalizeTrackingCookieValue(value) {
91
+ return typeof value === "string" && value.length > 0 ? value : null;
70
92
  }
71
- function createTrackingEventCreatePayload(trackingParams, input, context) {
72
- return {
73
- session_id: input.sessionId,
74
- event_type: input.eventType,
75
- gclid: trackingParams.gclid,
76
- fbclid: trackingParams.fbclid,
77
- page_url: input.pageUrl ?? (typeof window === "undefined" ? null : window.location.href),
78
- metadata: input.metadata ?? null,
79
- context
80
- };
93
+ function getTrackingParamsFromCookieReader(readCookie) {
94
+ return TRACKING_PARAM_KEYS.reduce((params, key) => {
95
+ params[key] = normalizeTrackingCookieValue(readCookie(key));
96
+ return params;
97
+ }, createEmptyTrackingParams());
98
+ }
99
+ function getTrackingQueryValues(searchParams) {
100
+ return TRACKING_PARAM_KEYS.reduce((params, key) => {
101
+ const value = searchParams.get(key);
102
+ if (typeof value === "string" && value.trim().length > 0) {
103
+ params[key] = value;
104
+ }
105
+ return params;
106
+ }, {});
107
+ }
108
+ var FALLBACK_STORAGE_PREFIX = "_aranova_track_";
109
+ function fallbackKey(name) {
110
+ return `${FALLBACK_STORAGE_PREFIX}${name}`;
111
+ }
112
+ function persistCookieValue(name, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
113
+ const encoded = encodeURIComponent(value);
114
+ if (typeof document !== "undefined") {
115
+ try {
116
+ document.cookie = `${name}=${encoded}; Max-Age=${maxAgeSeconds}; Path=/; SameSite=Lax`;
117
+ } catch {
118
+ }
119
+ }
120
+ if (typeof window !== "undefined") {
121
+ try {
122
+ window.localStorage.setItem(fallbackKey(name), encoded);
123
+ } catch {
124
+ }
125
+ }
126
+ }
127
+ function readCookieValue(name) {
128
+ if (typeof document !== "undefined") {
129
+ const cookies = document.cookie ? document.cookie.split("; ") : [];
130
+ const match = cookies.find((cookie) => cookie.startsWith(`${name}=`));
131
+ if (match) {
132
+ const [, rawValue = ""] = match.split("=");
133
+ return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
134
+ }
135
+ }
136
+ if (typeof window !== "undefined") {
137
+ try {
138
+ const stored = window.localStorage.getItem(fallbackKey(name));
139
+ if (stored) return normalizeTrackingCookieValue(decodeURIComponent(stored));
140
+ } catch {
141
+ }
142
+ }
143
+ return null;
144
+ }
145
+ function getCookieValueFromDocument(key) {
146
+ return readCookieValue(key);
147
+ }
148
+ function setTrackingCookie(key, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
149
+ persistCookieValue(key, value, maxAgeSeconds);
150
+ }
151
+ function mergeTrackingParams(primary, fallback) {
152
+ return TRACKING_PARAM_KEYS.reduce((merged, key) => {
153
+ merged[key] = primary[key] ?? fallback[key];
154
+ return merged;
155
+ }, createEmptyTrackingParams());
156
+ }
157
+ function persistTrackingParamsFromSearchParams(searchParams, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
158
+ const trackingValues = getTrackingQueryValues(searchParams);
159
+ Object.entries(trackingValues).forEach(([key, value]) => {
160
+ setTrackingCookie(key, value, maxAgeSeconds);
161
+ });
162
+ return trackingValues;
163
+ }
164
+ function captureTrackingParamsFromLocation(url = typeof window === "undefined" ? "" : window.location.href, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
165
+ const resolvedUrl = typeof window === "undefined" ? new URL(url || "https://example.invalid") : new URL(url, window.location.origin);
166
+ persistTrackingParamsFromSearchParams(resolvedUrl.searchParams, maxAgeSeconds);
167
+ return getTrackingParamsFromCookieReader(getCookieValueFromDocument);
81
168
  }
82
169
 
83
170
  // ../tracking-core/src/gtag.ts
@@ -98,6 +185,24 @@ function ensureGtagFunction() {
98
185
  };
99
186
  return window.gtag;
100
187
  }
188
+ var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
189
+ function isValidSendTo(sendTo) {
190
+ return SEND_TO_RE.test(sendTo);
191
+ }
192
+ function fireGtagConversion(input) {
193
+ if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
194
+ if (!isValidSendTo(input.sendTo)) return false;
195
+ const params = { send_to: input.sendTo };
196
+ if (input.value != null) params.value = input.value;
197
+ if (input.currency) params.currency = input.currency;
198
+ if (input.transactionId) params.transaction_id = input.transactionId;
199
+ try {
200
+ window.gtag("event", "conversion", params);
201
+ return true;
202
+ } catch {
203
+ return false;
204
+ }
205
+ }
101
206
  function applyDefaultConsentState() {
102
207
  const gtag = ensureGtagFunction();
103
208
  gtag("consent", "default", {
@@ -150,70 +255,441 @@ function bootstrapMultipleGtags(gtagIds) {
150
255
  restoreStoredConsent();
151
256
  }
152
257
 
153
- // ../tracking-core/src/tracking.ts
154
- var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
155
- var TRACKING_PARAM_KEYS = [
156
- "gclid",
157
- "fbclid",
158
- "utm_source",
159
- "utm_medium",
160
- "utm_campaign",
161
- "utm_term",
162
- "utm_content"
163
- ];
164
- function createEmptyTrackingParams() {
258
+ // ../tracking-core/src/fbq.ts
259
+ var FB_EVENTS_SCRIPT_HOST = "https://connect.facebook.net/en_US/fbevents.js";
260
+ var FBC_COOKIE = "_fbc";
261
+ var FBP_COOKIE = "_fbp";
262
+ var META_PIXEL_ID_PATTERN = /^\d{15,16}$/;
263
+ function isValidMetaPixelId(id) {
264
+ return META_PIXEL_ID_PATTERN.test(id);
265
+ }
266
+ function computeFbSubdomainIndex(hostname) {
267
+ const labels = hostname.split(".").filter(Boolean);
268
+ return Math.max(0, labels.length - 1);
269
+ }
270
+ function buildFbc(fbclid, now, hostname) {
271
+ const host = hostname ?? (typeof window === "undefined" ? "" : window.location.hostname);
272
+ return `fb.${computeFbSubdomainIndex(host)}.${now}.${fbclid}`;
273
+ }
274
+ function getFbcCookie() {
275
+ return readCookieValue(FBC_COOKIE);
276
+ }
277
+ function getFbpCookie() {
278
+ return readCookieValue(FBP_COOKIE);
279
+ }
280
+ function readFbclidFromUrl() {
281
+ if (typeof window === "undefined") return null;
282
+ try {
283
+ const value = new URL(window.location.href).searchParams.get("fbclid");
284
+ return value && value.trim().length > 0 ? value : null;
285
+ } catch {
286
+ return null;
287
+ }
288
+ }
289
+ function captureFbc(now = typeof Date === "undefined" ? 0 : Date.now()) {
290
+ if (typeof window === "undefined") return;
291
+ if (getFbcCookie()) return;
292
+ const fbclid = readFbclidFromUrl() ?? readCookieValue("fbclid");
293
+ if (!fbclid) return;
294
+ persistCookieValue(FBC_COOKIE, buildFbc(fbclid, now), TRACKING_COOKIE_MAX_AGE_SECONDS);
295
+ }
296
+ function getScriptMarker2(id) {
297
+ return `aranova-${id}`;
298
+ }
299
+ function ensureFbqFunction() {
300
+ const w = window;
301
+ if (typeof w.fbq === "function") return w.fbq;
302
+ const fbq = function(...args) {
303
+ if (fbq.callMethod) fbq.callMethod.apply(fbq, args);
304
+ else fbq.queue.push(args);
305
+ };
306
+ fbq.push = fbq;
307
+ fbq.loaded = true;
308
+ fbq.version = "2.0";
309
+ fbq.queue = [];
310
+ w.fbq = fbq;
311
+ if (!w._fbq) w._fbq = fbq;
312
+ return fbq;
313
+ }
314
+ function applyDefaultMetaConsentState() {
315
+ ensureFbqFunction()("consent", "revoke");
316
+ }
317
+ function loadFbeventsScript() {
318
+ if (typeof document === "undefined") return;
319
+ const marker = getScriptMarker2("fbq-loader");
320
+ const existing = document.querySelector(
321
+ `script[${TRACKING_SCRIPT_ATTRIBUTE}="${marker}"]`
322
+ );
323
+ if (existing) return;
324
+ const script = document.createElement("script");
325
+ script.async = true;
326
+ script.src = FB_EVENTS_SCRIPT_HOST;
327
+ script.setAttribute(TRACKING_SCRIPT_ATTRIBUTE, marker);
328
+ document.head.append(script);
329
+ }
330
+ function initializeMetaPixel(pixelId) {
331
+ const fbq = ensureFbqFunction();
332
+ fbq("init", pixelId);
333
+ fbq("track", "PageView");
334
+ }
335
+ function restoreMetaConsentState() {
336
+ if (typeof window === "undefined") return;
337
+ const state = getConsentState();
338
+ if (state === "granted") window.fbq?.("consent", "grant");
339
+ else if (state === "denied") window.fbq?.("consent", "revoke");
340
+ }
341
+ function bootstrapMetaPixel(pixelId) {
342
+ if (typeof window === "undefined" || typeof document === "undefined") return;
343
+ if (!isValidMetaPixelId(pixelId)) return;
344
+ applyDefaultMetaConsentState();
345
+ loadFbeventsScript();
346
+ initializeMetaPixel(pixelId);
347
+ restoreMetaConsentState();
348
+ captureFbc();
349
+ }
350
+ function bootstrapMultiplePixels(pixelIds) {
351
+ if (typeof window === "undefined" || typeof document === "undefined") return;
352
+ const ids = Object.values(pixelIds).filter(
353
+ (id) => typeof id === "string" && isValidMetaPixelId(id)
354
+ );
355
+ if (ids.length === 0) return;
356
+ applyDefaultMetaConsentState();
357
+ loadFbeventsScript();
358
+ const fbq = ensureFbqFunction();
359
+ for (const id of ids) {
360
+ fbq("init", id);
361
+ }
362
+ fbq("track", "PageView");
363
+ restoreMetaConsentState();
364
+ captureFbc();
365
+ }
366
+
367
+ // ../tracking-core/src/payloads.ts
368
+ function createTrackingClientContext(surface, input = {}) {
165
369
  return {
166
- gclid: null,
167
- fbclid: null,
168
- utm_source: null,
169
- utm_medium: null,
170
- utm_campaign: null,
171
- utm_term: null,
172
- utm_content: null
370
+ surface,
371
+ sdk_version: input.sdkVersion ?? null,
372
+ package_name: input.packageName ?? null,
373
+ site_origin: input.siteOrigin ?? (typeof window === "undefined" ? null : window.location.origin),
374
+ page_title: input.pageTitle ?? (typeof document === "undefined" ? null : document.title || null),
375
+ referrer: input.referrer ?? (typeof document === "undefined" ? null : document.referrer || null),
376
+ environment: input.environment ?? "production",
377
+ active_gtag_ids: input.activeGtagIds ?? null
173
378
  };
174
379
  }
175
- function normalizeTrackingCookieValue(value) {
176
- return typeof value === "string" && value.length > 0 ? value : null;
380
+ function createTrackingSessionUpsertPayload(trackingParams, input, context) {
381
+ return {
382
+ session_id: input.sessionId,
383
+ visitor_id: input.visitorId ?? null,
384
+ gclid: trackingParams.gclid,
385
+ fbclid: trackingParams.fbclid,
386
+ fbc: getFbcCookie(),
387
+ fbp: getFbpCookie(),
388
+ utm_source: trackingParams.utm_source,
389
+ utm_medium: trackingParams.utm_medium,
390
+ utm_campaign: trackingParams.utm_campaign,
391
+ utm_term: trackingParams.utm_term,
392
+ utm_content: trackingParams.utm_content,
393
+ first_page: input.firstPage ?? null,
394
+ consent_state: input.consentState ?? null,
395
+ context
396
+ };
177
397
  }
178
- function getTrackingParamsFromCookieReader(readCookie) {
179
- return TRACKING_PARAM_KEYS.reduce((params, key) => {
180
- params[key] = normalizeTrackingCookieValue(readCookie(key));
181
- return params;
182
- }, createEmptyTrackingParams());
398
+ function createTrackingEventCreatePayload(trackingParams, input, context) {
399
+ return {
400
+ session_id: input.sessionId,
401
+ event_type: input.eventType,
402
+ gclid: trackingParams.gclid,
403
+ fbclid: trackingParams.fbclid,
404
+ fbc: getFbcCookie(),
405
+ fbp: getFbpCookie(),
406
+ page_url: input.pageUrl ?? (typeof window === "undefined" ? null : window.location.href),
407
+ metadata: input.metadata ?? null,
408
+ context
409
+ };
183
410
  }
184
- function getTrackingQueryValues(searchParams) {
185
- return TRACKING_PARAM_KEYS.reduce((params, key) => {
186
- const value = searchParams.get(key);
187
- if (typeof value === "string" && value.trim().length > 0) {
188
- params[key] = value;
189
- }
190
- return params;
191
- }, {});
411
+
412
+ // ../tracking-core/src/resources/conversion-firing.ts
413
+ var DEDUP_PREFIX = "_aranova_conv_";
414
+ var MAX_PENDING = 100;
415
+ var pendingQueue = [];
416
+ function dedupKey(input) {
417
+ return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
418
+ }
419
+ function alreadyFired(input) {
420
+ if (!input.transactionId || typeof window === "undefined") return false;
421
+ try {
422
+ return window.sessionStorage.getItem(dedupKey(input)) !== null;
423
+ } catch {
424
+ return false;
425
+ }
192
426
  }
193
- function getCookieValueFromDocument(key) {
194
- if (typeof document === "undefined") return null;
195
- const cookies = document.cookie ? document.cookie.split("; ") : [];
196
- const match = cookies.find((cookie) => cookie.startsWith(`${key}=`));
197
- if (!match) return null;
198
- const [, rawValue = ""] = match.split("=");
199
- return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
427
+ function markFired(input) {
428
+ if (!input.transactionId || typeof window === "undefined") return;
429
+ try {
430
+ window.sessionStorage.setItem(dedupKey(input), "1");
431
+ } catch {
432
+ }
200
433
  }
201
- function setTrackingCookie(key, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
202
- if (typeof document === "undefined") return;
203
- const encodedValue = encodeURIComponent(value);
204
- document.cookie = `${key}=${encodedValue}; Max-Age=${maxAgeSeconds}; Path=/; SameSite=Lax`;
434
+ function fireOnce(input) {
435
+ if (alreadyFired(input)) return;
436
+ if (fireGtagConversion(input)) markFired(input);
205
437
  }
206
- function persistTrackingParamsFromSearchParams(searchParams, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
207
- const trackingValues = getTrackingQueryValues(searchParams);
208
- Object.entries(trackingValues).forEach(([key, value]) => {
209
- setTrackingCookie(key, value, maxAgeSeconds);
438
+ function fireConversionWithConsent(input) {
439
+ const state = getConsentState();
440
+ if (state === "denied") return;
441
+ if (state === "pending") {
442
+ if (pendingQueue.length >= MAX_PENDING) pendingQueue.shift();
443
+ pendingQueue.push(input);
444
+ return;
445
+ }
446
+ fireOnce(input);
447
+ }
448
+ function flushPendingConversions() {
449
+ if (getConsentState() !== "granted") return;
450
+ while (pendingQueue.length > 0) {
451
+ const input = pendingQueue.shift();
452
+ if (input) fireOnce(input);
453
+ }
454
+ }
455
+ if (typeof window !== "undefined") onConsentGranted(flushPendingConversions);
456
+
457
+ // ../tracking-core/src/resources/conversion-config.ts
458
+ function isStringMap(value) {
459
+ return typeof value === "object" && value !== null && Object.values(value).every((v) => typeof v === "string");
460
+ }
461
+ function parseFiring(value) {
462
+ if (!value || typeof value !== "object") return null;
463
+ const f = value;
464
+ if (typeof f.send_to !== "string") return null;
465
+ return {
466
+ send_to: f.send_to,
467
+ value_cents: typeof f.value_cents === "number" ? f.value_cents : null,
468
+ currency: typeof f.currency === "string" ? f.currency : null
469
+ };
470
+ }
471
+ function parseTrigger(value) {
472
+ if (!value || typeof value !== "object") return null;
473
+ const t = value;
474
+ if (typeof t.event_type !== "string") return null;
475
+ const spec = { event_type: t.event_type };
476
+ if (typeof t.threshold_percent === "number") spec.threshold_percent = t.threshold_percent;
477
+ if (typeof t.threshold_seconds === "number") spec.threshold_seconds = t.threshold_seconds;
478
+ if (typeof t.page_threshold === "number") spec.page_threshold = t.page_threshold;
479
+ if (typeof t.page_name === "string") spec.page_name = t.page_name;
480
+ return spec;
481
+ }
482
+ function parseConversionConfig(raw) {
483
+ if (!raw || typeof raw !== "object") return null;
484
+ const obj = raw;
485
+ const servicesRaw = Array.isArray(obj.services) ? obj.services : [];
486
+ const services = servicesRaw.flatMap((entry) => {
487
+ if (!entry || typeof entry !== "object") return [];
488
+ const s = entry;
489
+ if (typeof s.key !== "string") return [];
490
+ return [
491
+ {
492
+ key: s.key,
493
+ label: typeof s.label === "string" ? s.label : void 0,
494
+ firing: parseFiring(s.firing)
495
+ }
496
+ ];
210
497
  });
211
- return trackingValues;
498
+ const goalsRaw = Array.isArray(obj.goals) ? obj.goals : null;
499
+ const goals = goalsRaw ? goalsRaw.flatMap((entry) => {
500
+ if (!entry || typeof entry !== "object") return [];
501
+ const g = entry;
502
+ if (typeof g.key !== "string") return [];
503
+ return [
504
+ {
505
+ key: g.key,
506
+ label: typeof g.label === "string" ? g.label : void 0,
507
+ kind: g.kind === "event" ? "event" : "sale",
508
+ trigger: parseTrigger(g.trigger),
509
+ firing: parseFiring(g.firing)
510
+ }
511
+ ];
512
+ }) : services.map((s) => ({
513
+ key: s.key,
514
+ label: s.label,
515
+ kind: "sale",
516
+ trigger: null,
517
+ firing: s.firing
518
+ }));
519
+ return {
520
+ schema_version: typeof obj.schema_version === "number" ? obj.schema_version : 1,
521
+ config_version: typeof obj.config_version === "number" ? obj.config_version : 0,
522
+ business_id: typeof obj.business_id === "string" ? obj.business_id : void 0,
523
+ customer_id: typeof obj.customer_id === "string" ? obj.customer_id : null,
524
+ environment: typeof obj.environment === "string" ? obj.environment : void 0,
525
+ gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
526
+ meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
527
+ services,
528
+ goals
529
+ };
212
530
  }
213
- function captureTrackingParamsFromLocation(url = typeof window === "undefined" ? "" : window.location.href, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
214
- const resolvedUrl = typeof window === "undefined" ? new URL(url || "https://example.invalid") : new URL(url, window.location.origin);
215
- persistTrackingParamsFromSearchParams(resolvedUrl.searchParams, maxAgeSeconds);
216
- return getTrackingParamsFromCookieReader(getCookieValueFromDocument);
531
+ var CACHE_PREFIX = "_aranova_cfg_";
532
+ function cacheKey(url) {
533
+ return `${CACHE_PREFIX}${url}`;
534
+ }
535
+ function readCache(url) {
536
+ if (typeof window === "undefined") return null;
537
+ try {
538
+ const raw = window.sessionStorage.getItem(cacheKey(url));
539
+ if (!raw) return null;
540
+ const parsed = JSON.parse(raw);
541
+ const config = parseConversionConfig(parsed.config);
542
+ if (!config) return null;
543
+ return {
544
+ etag: typeof parsed.etag === "string" ? parsed.etag : null,
545
+ config
546
+ };
547
+ } catch {
548
+ return null;
549
+ }
550
+ }
551
+ function writeCache(url, entry) {
552
+ if (typeof window === "undefined") return;
553
+ try {
554
+ window.sessionStorage.setItem(cacheKey(url), JSON.stringify(entry));
555
+ } catch {
556
+ }
557
+ }
558
+ function resolveConversionConfig(options) {
559
+ const cached = readCache(options.cdnUrl);
560
+ let current = cached?.config ?? options.baked ?? null;
561
+ let etag = cached?.etag ?? null;
562
+ const goalsByKey = /* @__PURE__ */ new Map();
563
+ function rebuildIndex() {
564
+ goalsByKey.clear();
565
+ for (const goal of current?.goals ?? []) {
566
+ goalsByKey.set(goal.key, goal);
567
+ }
568
+ }
569
+ function adopt(next, nextEtag) {
570
+ if (!next) return;
571
+ if (current && next.config_version <= current.config_version) return;
572
+ current = next;
573
+ etag = nextEtag;
574
+ rebuildIndex();
575
+ writeCache(options.cdnUrl, { etag, config: next });
576
+ }
577
+ async function revalidate() {
578
+ if (typeof window === "undefined") return;
579
+ try {
580
+ const doFetch = options.fetchImpl ?? globalThis.fetch;
581
+ if (!doFetch) return;
582
+ const headers = {};
583
+ if (etag) headers["If-None-Match"] = etag;
584
+ const response = await doFetch(options.cdnUrl, {
585
+ method: "GET",
586
+ headers
587
+ });
588
+ if (response.status === 304 || !response.ok) return;
589
+ adopt(parseConversionConfig(await response.json()), response.headers.get("ETag"));
590
+ } catch {
591
+ }
592
+ }
593
+ rebuildIndex();
594
+ void revalidate();
595
+ return {
596
+ getFiring: (key) => goalsByKey.get(key)?.firing ?? null,
597
+ getGoal: (key) => goalsByKey.get(key) ?? null,
598
+ listGoals: () => [...goalsByKey.values()],
599
+ current: () => current,
600
+ revalidate
601
+ };
602
+ }
603
+
604
+ // ../tracking-core/src/resources/sales/money.ts
605
+ var MINOR_UNIT_EXPONENT = {
606
+ USD: 2,
607
+ CAD: 2
608
+ };
609
+ function exponentFor(currency) {
610
+ return MINOR_UNIT_EXPONENT[currency] ?? 2;
611
+ }
612
+ function toMinor(amount, currency) {
613
+ return Math.round(amount * 10 ** exponentFor(currency));
614
+ }
615
+ function fromMinor(cents, currency) {
616
+ return cents / 10 ** exponentFor(currency);
617
+ }
618
+ function formatMoney(cents, currency, locale) {
619
+ return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
620
+ fromMinor(cents, currency)
621
+ );
622
+ }
623
+ function formatDateInTz(iso, timeZone, opts, locale) {
624
+ const date = new Date(iso);
625
+ if (Number.isNaN(date.getTime())) return iso;
626
+ return new Intl.DateTimeFormat(locale, {
627
+ year: "numeric",
628
+ month: "short",
629
+ day: "2-digit",
630
+ hour: "2-digit",
631
+ minute: "2-digit",
632
+ ...opts,
633
+ timeZone
634
+ }).format(date);
635
+ }
636
+
637
+ // ../tracking-core/src/resources/conversion-autofire.ts
638
+ function thresholdMet(goal, eventType, metadata) {
639
+ const t = goal.trigger;
640
+ if (!t || t.event_type !== eventType) return false;
641
+ switch (eventType) {
642
+ case "scroll_depth":
643
+ return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
644
+ case "time_on_site":
645
+ return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
646
+ case "multi_page_session":
647
+ return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
648
+ case "specific_page_visit":
649
+ return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
650
+ case "page_view":
651
+ case "form_start":
652
+ return true;
653
+ // no threshold — fire whenever the detector emits
654
+ default:
655
+ return false;
656
+ }
657
+ }
658
+ function currentPath() {
659
+ return typeof window === "undefined" ? "" : window.location.pathname;
660
+ }
661
+ function createConversionAutoFire(store) {
662
+ return {
663
+ onAutomaticEvent(eventType, metadata) {
664
+ for (const goal of store.listGoals()) {
665
+ if (goal.kind !== "event" || !goal.firing) continue;
666
+ if (!thresholdMet(goal, eventType, metadata)) continue;
667
+ const firing = goal.firing;
668
+ const cents = firing.value_cents ?? null;
669
+ const currency = firing.currency ?? null;
670
+ fireConversionWithConsent({
671
+ sendTo: firing.send_to,
672
+ value: cents != null && currency ? fromMinor(cents, currency) : null,
673
+ currency,
674
+ // Page-scoped txn id → fire once per (goal, path) per session; engagement conversions
675
+ // shouldn't re-fire as the visitor scrolls back and forth or re-enters a page.
676
+ transactionId: `auto:${goal.key}:${currentPath()}`
677
+ });
678
+ }
679
+ }
680
+ };
681
+ }
682
+ function withConversionAutoFire(client, autoFire) {
683
+ return {
684
+ ...client,
685
+ trackEvent: (input) => {
686
+ client.trackEvent(input);
687
+ try {
688
+ autoFire.onAutomaticEvent(input.eventType, input.metadata ?? {});
689
+ } catch {
690
+ }
691
+ }
692
+ };
217
693
  }
218
694
 
219
695
  // ../tracking-core/src/session.ts
@@ -544,11 +1020,22 @@ function createTrackingClient(config) {
544
1020
  let queue = [];
545
1021
  let flushTimer = null;
546
1022
  let firstPage = null;
1023
+ let initialParams = createEmptyTrackingParams();
547
1024
  let destroyed = false;
548
1025
  const visitorId = getVisitorId();
549
1026
  const initialSession = getOrRotateSessionId();
550
1027
  let sessionId = initialSession.id;
551
- if (typeof window !== "undefined") firstPage = window.location.href;
1028
+ if (typeof window !== "undefined") {
1029
+ firstPage = window.location.href;
1030
+ try {
1031
+ initialParams = captureTrackingParamsFromLocation();
1032
+ } catch {
1033
+ }
1034
+ try {
1035
+ captureFbc();
1036
+ } catch {
1037
+ }
1038
+ }
552
1039
  function enqueueHeartbeat() {
553
1040
  const metadata = buildHeartbeatMetadata(
554
1041
  config.surface,
@@ -573,7 +1060,7 @@ function createTrackingClient(config) {
573
1060
  enqueueHeartbeat();
574
1061
  }
575
1062
  sessionId = rotated.id;
576
- const params = readTrackingParams();
1063
+ const params = mergeTrackingParams(readTrackingParams(), initialParams);
577
1064
  const context = buildContext(
578
1065
  config.surface,
579
1066
  sdkVersion,
@@ -586,6 +1073,8 @@ function createTrackingClient(config) {
586
1073
  visitor_id: visitorId,
587
1074
  gclid: params.gclid,
588
1075
  fbclid: params.fbclid,
1076
+ fbc: getFbcCookie(),
1077
+ fbp: getFbpCookie(),
589
1078
  utm_source: params.utm_source,
590
1079
  utm_medium: params.utm_medium,
591
1080
  utm_campaign: params.utm_campaign,
@@ -1022,7 +1511,7 @@ function attachScrollDepth(client, config) {
1022
1511
  }
1023
1512
  const thresholds = new Set(config.thresholds);
1024
1513
  let firedForPath = /* @__PURE__ */ new Set();
1025
- let currentPath = window.location.pathname;
1514
+ let currentPath2 = window.location.pathname;
1026
1515
  let rafId = null;
1027
1516
  function getScrollPercent() {
1028
1517
  const doc = document.documentElement;
@@ -1041,7 +1530,7 @@ function attachScrollDepth(client, config) {
1041
1530
  eventType: "scroll_depth",
1042
1531
  metadata: {
1043
1532
  depth_percent: threshold,
1044
- page: { path: currentPath }
1533
+ page: { path: currentPath2 }
1045
1534
  },
1046
1535
  pageUrl: window.location.href,
1047
1536
  occurredAt: null
@@ -1058,8 +1547,8 @@ function attachScrollDepth(client, config) {
1058
1547
  }
1059
1548
  function resetIfPathChanged() {
1060
1549
  const newPath = window.location.pathname;
1061
- if (newPath === currentPath) return;
1062
- currentPath = newPath;
1550
+ if (newPath === currentPath2) return;
1551
+ currentPath2 = newPath;
1063
1552
  firedForPath = /* @__PURE__ */ new Set();
1064
1553
  setTimeout(checkThresholds, 0);
1065
1554
  }
@@ -1135,13 +1624,13 @@ function attachMultiPageSession(client, config) {
1135
1624
  return storage.getItem(FIRED_KEY) === "1";
1136
1625
  }
1137
1626
  function check() {
1138
- const currentPath = window.location.pathname;
1139
- if (currentPath === lastCheckedPath) return;
1140
- lastCheckedPath = currentPath;
1627
+ const currentPath2 = window.location.pathname;
1628
+ if (currentPath2 === lastCheckedPath) return;
1629
+ lastCheckedPath = currentPath2;
1141
1630
  resetIfSessionChanged();
1142
1631
  if (hasFired()) return;
1143
1632
  const paths = getDistinctPaths();
1144
- paths.add(currentPath);
1633
+ paths.add(currentPath2);
1145
1634
  saveDistinctPaths(paths);
1146
1635
  if (paths.size >= pageThreshold) {
1147
1636
  storage.setItem(FIRED_KEY, "1");
@@ -1185,7 +1674,7 @@ function attachFormStart(client, config) {
1185
1674
  }
1186
1675
  const selector = config.selector ?? "form";
1187
1676
  let firedForms = /* @__PURE__ */ new Set();
1188
- let currentPath = window.location.pathname;
1677
+ let currentPath2 = window.location.pathname;
1189
1678
  function getFormKey(form) {
1190
1679
  if (form.id) return `id:${form.id}`;
1191
1680
  const explicitAction = form.getAttribute("action");
@@ -1216,8 +1705,8 @@ function attachFormStart(client, config) {
1216
1705
  }
1217
1706
  function resetIfPathChanged() {
1218
1707
  const newPath = window.location.pathname;
1219
- if (newPath === currentPath) return;
1220
- currentPath = newPath;
1708
+ if (newPath === currentPath2) return;
1709
+ currentPath2 = newPath;
1221
1710
  firedForms = /* @__PURE__ */ new Set();
1222
1711
  }
1223
1712
  const originalPushState = history.pushState.bind(history);
@@ -1296,21 +1785,64 @@ async function salesRequest(config, method, path, body) {
1296
1785
  }
1297
1786
 
1298
1787
  // ../tracking-core/src/resources/sales/client.ts
1788
+ function fireRecordedConversions(firing, input, recorded, sale, currency) {
1789
+ if (!firing) return;
1790
+ const txnBase = input.external_id ?? sale.id;
1791
+ for (const item of recorded) {
1792
+ if (!item.service) continue;
1793
+ const config = firing.getFiring(item.service);
1794
+ if (!config) continue;
1795
+ const cents = item.amount_cents ?? config.value_cents ?? null;
1796
+ fireConversionWithConsent({
1797
+ sendTo: config.send_to,
1798
+ value: cents != null ? fromMinor(cents, currency) : null,
1799
+ currency: config.currency ?? currency,
1800
+ transactionId: `${txnBase}:${item.service}`
1801
+ });
1802
+ }
1803
+ }
1299
1804
  function createSalesClient(config) {
1300
- return {
1301
- async record(input) {
1302
- const currency = input.currency ?? config.defaultCurrency;
1303
- if (!currency) {
1304
- throw new Error(
1305
- "record: `currency` is required (pass it on the sale or set config.defaultCurrency)"
1306
- );
1805
+ async function record(input) {
1806
+ const currency = input.currency ?? config.defaultCurrency;
1807
+ if (!currency) {
1808
+ throw new Error(
1809
+ "record: `currency` is required (pass it on the sale or set config.defaultCurrency)"
1810
+ );
1811
+ }
1812
+ const body = {
1813
+ ...input,
1814
+ currency,
1815
+ occurred_at: input.occurred_at ?? (/* @__PURE__ */ new Date()).toISOString()
1816
+ };
1817
+ const sale = await salesRequest(config, "POST", "/sales", body);
1818
+ const recorded = input.services?.length ? input.services.map((s) => ({
1819
+ service: s.service,
1820
+ amount_cents: s.amount_cents
1821
+ })) : [
1822
+ {
1823
+ service: input.service,
1824
+ amount_cents: input.amount_total_cents ?? null
1307
1825
  }
1308
- const body = {
1309
- ...input,
1826
+ ];
1827
+ fireRecordedConversions(config.firing, input, recorded, sale, currency);
1828
+ return sale;
1829
+ }
1830
+ return {
1831
+ record,
1832
+ // recordSale is the intent-revealing alias — same behavior, clearer call site.
1833
+ recordSale: record,
1834
+ trackConversion(key, options) {
1835
+ const firing = config.firing?.getFiring(key);
1836
+ if (!firing) return;
1837
+ const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
1838
+ const cents = firing.value_cents ?? null;
1839
+ const value = options?.value ?? (cents != null && currency ? fromMinor(cents, currency) : null);
1840
+ fireConversionWithConsent({
1841
+ sendTo: firing.send_to,
1842
+ value,
1310
1843
  currency,
1311
- occurred_at: input.occurred_at ?? (/* @__PURE__ */ new Date()).toISOString()
1312
- };
1313
- return salesRequest(config, "POST", "/sales", body);
1844
+ transactionId: options?.transactionId ?? null
1845
+ });
1314
1846
  },
1315
1847
  async list(query) {
1316
1848
  const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
@@ -1404,39 +1936,6 @@ function createSalesClient(config) {
1404
1936
  };
1405
1937
  }
1406
1938
 
1407
- // ../tracking-core/src/resources/sales/money.ts
1408
- var MINOR_UNIT_EXPONENT = {
1409
- USD: 2,
1410
- CAD: 2
1411
- };
1412
- function exponentFor(currency) {
1413
- return MINOR_UNIT_EXPONENT[currency] ?? 2;
1414
- }
1415
- function toMinor(amount, currency) {
1416
- return Math.round(amount * 10 ** exponentFor(currency));
1417
- }
1418
- function fromMinor(cents, currency) {
1419
- return cents / 10 ** exponentFor(currency);
1420
- }
1421
- function formatMoney(cents, currency, locale) {
1422
- return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
1423
- fromMinor(cents, currency)
1424
- );
1425
- }
1426
- function formatDateInTz(iso, timeZone, opts, locale) {
1427
- const date = new Date(iso);
1428
- if (Number.isNaN(date.getTime())) return iso;
1429
- return new Intl.DateTimeFormat(locale, {
1430
- year: "numeric",
1431
- month: "short",
1432
- day: "2-digit",
1433
- hour: "2-digit",
1434
- minute: "2-digit",
1435
- ...opts,
1436
- timeZone
1437
- }).format(date);
1438
- }
1439
-
1440
1939
  // ../tracking-core/src/resources/sales/schema.ts
1441
1940
  import { z as z11 } from "zod";
1442
1941
  var SUPPORTED_CURRENCIES = ["USD", "CAD"];
@@ -1835,11 +2334,19 @@ var ANIMATION_KEYFRAMES = `
1835
2334
  }
1836
2335
  `;
1837
2336
 
1838
- // src/GoogleAdsTracking.tsx
2337
+ // src/AdPlatformTracking.tsx
1839
2338
  import { useEffect as useEffect3, useMemo } from "react";
1840
- function GoogleAdsTracking(props) {
1841
- const { gtagId, gtagIds } = props;
2339
+ function AdPlatformTracking({
2340
+ gtagId,
2341
+ gtagIds,
2342
+ metaPixelId,
2343
+ metaPixelIds
2344
+ }) {
1842
2345
  const gtagIdsKey = useMemo(() => gtagIds ? JSON.stringify(gtagIds) : "", [gtagIds]);
2346
+ const metaPixelIdsKey = useMemo(
2347
+ () => metaPixelIds ? JSON.stringify(metaPixelIds) : "",
2348
+ [metaPixelIds]
2349
+ );
1843
2350
  useEffect3(() => {
1844
2351
  if (gtagIds && Object.keys(gtagIds).length > 0) {
1845
2352
  bootstrapMultipleGtags(gtagIds);
@@ -1847,14 +2354,36 @@ function GoogleAdsTracking(props) {
1847
2354
  bootstrapGoogleAdsTracking(gtagId);
1848
2355
  }
1849
2356
  }, [gtagId, gtagIdsKey]);
2357
+ useEffect3(() => {
2358
+ if (metaPixelIds && Object.keys(metaPixelIds).length > 0) {
2359
+ bootstrapMultiplePixels(metaPixelIds);
2360
+ } else if (metaPixelId) {
2361
+ bootstrapMetaPixel(metaPixelId);
2362
+ }
2363
+ }, [metaPixelId, metaPixelIdsKey]);
2364
+ return null;
2365
+ }
2366
+
2367
+ // src/GoogleAdsTracking.tsx
2368
+ import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
2369
+ function GoogleAdsTracking(props) {
2370
+ const { gtagId, gtagIds } = props;
2371
+ const gtagIdsKey = useMemo2(() => gtagIds ? JSON.stringify(gtagIds) : "", [gtagIds]);
2372
+ useEffect4(() => {
2373
+ if (gtagIds && Object.keys(gtagIds).length > 0) {
2374
+ bootstrapMultipleGtags(gtagIds);
2375
+ } else if (gtagId) {
2376
+ bootstrapGoogleAdsTracking(gtagId);
2377
+ }
2378
+ }, [gtagId, gtagIdsKey]);
1850
2379
  return null;
1851
2380
  }
1852
2381
 
1853
2382
  // src/factory.tsx
1854
- import { createContext as createContext2, useContext as useContext2, useEffect as useEffect4, useMemo as useMemo3 } from "react";
2383
+ import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
1855
2384
 
1856
2385
  // package.json
1857
- var version = "0.12.2";
2386
+ var version = "0.14.0";
1858
2387
 
1859
2388
  // ../tracking-core/src/phone-react.tsx
1860
2389
  import {
@@ -1862,7 +2391,7 @@ import {
1862
2391
  forwardRef,
1863
2392
  useCallback as useCallback2,
1864
2393
  useContext,
1865
- useMemo as useMemo2,
2394
+ useMemo as useMemo3,
1866
2395
  useState as useState3
1867
2396
  } from "react";
1868
2397
  import { jsx as jsx2 } from "react/jsx-runtime";
@@ -1891,7 +2420,7 @@ function usePhoneField(opts = {}) {
1891
2420
  const { onValueChange } = opts;
1892
2421
  const [value, setValue] = useState3(() => formatPhoneAsTyped(opts.defaultValue ?? "", country));
1893
2422
  const [touched, setTouched] = useState3(false);
1894
- const parsed = useMemo2(() => parsePhone(value, country), [value, country]);
2423
+ const parsed = useMemo3(() => parsePhone(value, country), [value, country]);
1895
2424
  const onChange = useCallback2(
1896
2425
  (event) => {
1897
2426
  const next = formatPhoneAsTyped(event.target.value, country);
@@ -1960,7 +2489,7 @@ var NOOP_CLIENT = {
1960
2489
  getVisitorId: () => ""
1961
2490
  };
1962
2491
  function createTracking(options) {
1963
- const { apiKey, endpoint, triggers, environment, debug, phone } = options;
2492
+ const { apiKey, endpoint, triggers, environment, debug, phone, conversionConfig } = options;
1964
2493
  if (!apiKey || !endpoint) {
1965
2494
  if (apiKey || endpoint) {
1966
2495
  console.warn(
@@ -1976,11 +2505,17 @@ function createTracking(options) {
1976
2505
  };
1977
2506
  }
1978
2507
  const TrackingContext = createContext2(null);
1979
- function TrackingProvider({ gtagId, gtagIds, children }) {
2508
+ function TrackingProvider({
2509
+ gtagId,
2510
+ gtagIds,
2511
+ metaPixelId,
2512
+ metaPixelIds,
2513
+ children
2514
+ }) {
1980
2515
  const resolvedGtagIds = gtagIds ? Object.fromEntries(
1981
2516
  Object.entries(gtagIds).filter((e) => e[1] != null)
1982
2517
  ) : gtagId ? { default: gtagId } : void 0;
1983
- const client = useMemo3(
2518
+ const client = useMemo4(
1984
2519
  () => createTypedClient(
1985
2520
  getOrCreateTrackingClient({
1986
2521
  apiKey,
@@ -1998,15 +2533,26 @@ function createTracking(options) {
1998
2533
  ),
1999
2534
  []
2000
2535
  );
2001
- const gtagIdsKey = useMemo3(() => gtagIds ? JSON.stringify(gtagIds) : "", [gtagIds]);
2002
- useEffect4(() => {
2536
+ const gtagIdsKey = useMemo4(() => gtagIds ? JSON.stringify(gtagIds) : "", [gtagIds]);
2537
+ useEffect5(() => {
2003
2538
  if (gtagIds && Object.keys(gtagIds).length > 0) {
2004
2539
  bootstrapMultipleGtags(gtagIds);
2005
2540
  } else if (gtagId) {
2006
2541
  bootstrapGoogleAdsTracking(gtagId);
2007
2542
  }
2008
2543
  }, [gtagId, gtagIdsKey]);
2009
- useEffect4(() => {
2544
+ const metaPixelIdsKey = useMemo4(
2545
+ () => metaPixelIds ? JSON.stringify(metaPixelIds) : "",
2546
+ [metaPixelIds]
2547
+ );
2548
+ useEffect5(() => {
2549
+ if (metaPixelIds && Object.keys(metaPixelIds).length > 0) {
2550
+ bootstrapMultiplePixels(metaPixelIds);
2551
+ } else if (metaPixelId) {
2552
+ bootstrapMetaPixel(metaPixelId);
2553
+ }
2554
+ }, [metaPixelId, metaPixelIdsKey]);
2555
+ useEffect5(() => {
2010
2556
  const detachers = [];
2011
2557
  const rawClient = getOrCreateTrackingClient({
2012
2558
  apiKey,
@@ -2018,27 +2564,32 @@ function createTracking(options) {
2018
2564
  activeGtagIds: resolvedGtagIds,
2019
2565
  debug
2020
2566
  });
2021
- detachers.push(attachAutoPageView(rawClient));
2022
- detachers.push(attachBfcacheRestore(rawClient));
2567
+ const conversionStore = conversionConfig ? resolveConversionConfig({
2568
+ cdnUrl: conversionConfig.cdnUrl,
2569
+ baked: conversionConfig.baked
2570
+ }) : null;
2571
+ const detectorClient = conversionStore ? withConversionAutoFire(rawClient, createConversionAutoFire(conversionStore)) : rawClient;
2572
+ detachers.push(attachAutoPageView(detectorClient));
2573
+ detachers.push(attachBfcacheRestore(detectorClient));
2023
2574
  const timeOnSite = triggers.automatic.time_on_site;
2024
2575
  if (timeOnSite) {
2025
- detachers.push(attachTimeOnSite(rawClient, timeOnSite));
2576
+ detachers.push(attachTimeOnSite(detectorClient, timeOnSite));
2026
2577
  }
2027
2578
  const specificPageVisit = triggers.automatic.specific_page_visit;
2028
2579
  if (specificPageVisit) {
2029
- detachers.push(attachSpecificPageVisit(rawClient, specificPageVisit));
2580
+ detachers.push(attachSpecificPageVisit(detectorClient, specificPageVisit));
2030
2581
  }
2031
2582
  const scrollDepth = triggers.automatic.scroll_depth;
2032
2583
  if (scrollDepth) {
2033
- detachers.push(attachScrollDepth(rawClient, scrollDepth));
2584
+ detachers.push(attachScrollDepth(detectorClient, scrollDepth));
2034
2585
  }
2035
2586
  const multiPageSession = triggers.automatic.multi_page_session;
2036
2587
  if (multiPageSession) {
2037
- detachers.push(attachMultiPageSession(rawClient, multiPageSession));
2588
+ detachers.push(attachMultiPageSession(detectorClient, multiPageSession));
2038
2589
  }
2039
2590
  const formStart = triggers.automatic.form_start;
2040
2591
  if (formStart) {
2041
- detachers.push(attachFormStart(rawClient, formStart));
2592
+ detachers.push(attachFormStart(detectorClient, formStart));
2042
2593
  }
2043
2594
  return () => {
2044
2595
  for (let i = detachers.length - 1; i >= 0; i--) {
@@ -2060,6 +2611,7 @@ function createTracking(options) {
2060
2611
  return { TrackingProvider, useTracking };
2061
2612
  }
2062
2613
  export {
2614
+ AdPlatformTracking,
2063
2615
  AranovaApiError,
2064
2616
  ConsentBanner,
2065
2617
  DEFAULT_PHONE_COUNTRY,
@@ -2085,6 +2637,7 @@ export {
2085
2637
  parsePhone,
2086
2638
  phoneField,
2087
2639
  resetConsent,
2640
+ resolveConversionConfig,
2088
2641
  saleCreateSchema,
2089
2642
  saleItemSchema,
2090
2643
  saleServiceSchema,