@aranova/tracking-next 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
@@ -1,6 +1,13 @@
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 grantedListeners = /* @__PURE__ */ new Set();
5
+ function onConsentGranted(listener) {
6
+ grantedListeners.add(listener);
7
+ return () => {
8
+ grantedListeners.delete(listener);
9
+ };
10
+ }
4
11
  function buildConsentPayload(state) {
5
12
  return {
6
13
  ad_storage: state,
@@ -11,62 +18,142 @@ function buildConsentPayload(state) {
11
18
  }
12
19
  function getConsentState() {
13
20
  if (typeof window === "undefined") return "pending";
14
- const storedState = window.localStorage.getItem(CONSENT_STATE_KEY);
15
- if (storedState === "granted" || storedState === "denied") return storedState;
21
+ try {
22
+ const storedState = window.localStorage.getItem(CONSENT_STATE_KEY);
23
+ if (storedState === "granted" || storedState === "denied") return storedState;
24
+ } catch {
25
+ }
16
26
  return "pending";
17
27
  }
18
28
  function setConsentState(state) {
19
29
  if (typeof window === "undefined") return;
20
- window.localStorage.setItem(CONSENT_STATE_KEY, state);
21
- window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
30
+ try {
31
+ window.localStorage.setItem(CONSENT_STATE_KEY, state);
32
+ window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
33
+ } catch {
34
+ }
22
35
  if (typeof window.gtag === "function")
23
36
  window.gtag("consent", "update", buildConsentPayload(state));
37
+ if (typeof window.fbq === "function")
38
+ window.fbq("consent", state === "granted" ? "grant" : "revoke");
39
+ if (state === "granted") {
40
+ for (const listener of grantedListeners) {
41
+ try {
42
+ listener();
43
+ } catch {
44
+ }
45
+ }
46
+ }
24
47
  }
25
48
  function resetConsent() {
26
49
  if (typeof window === "undefined") return;
27
- window.localStorage.removeItem(CONSENT_STATE_KEY);
28
- window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
50
+ try {
51
+ window.localStorage.removeItem(CONSENT_STATE_KEY);
52
+ window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
53
+ } catch {
54
+ }
29
55
  }
30
56
 
31
- // ../tracking-core/src/payloads.ts
32
- function createTrackingClientContext(surface, input = {}) {
57
+ // ../tracking-core/src/tracking.ts
58
+ var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
59
+ var TRACKING_PARAM_KEYS = [
60
+ "gclid",
61
+ "fbclid",
62
+ "utm_source",
63
+ "utm_medium",
64
+ "utm_campaign",
65
+ "utm_term",
66
+ "utm_content"
67
+ ];
68
+ function createEmptyTrackingParams() {
33
69
  return {
34
- surface,
35
- sdk_version: input.sdkVersion ?? null,
36
- package_name: input.packageName ?? null,
37
- site_origin: input.siteOrigin ?? (typeof window === "undefined" ? null : window.location.origin),
38
- page_title: input.pageTitle ?? (typeof document === "undefined" ? null : document.title || null),
39
- referrer: input.referrer ?? (typeof document === "undefined" ? null : document.referrer || null),
40
- environment: input.environment ?? "production",
41
- active_gtag_ids: input.activeGtagIds ?? null
70
+ gclid: null,
71
+ fbclid: null,
72
+ utm_source: null,
73
+ utm_medium: null,
74
+ utm_campaign: null,
75
+ utm_term: null,
76
+ utm_content: null
42
77
  };
43
78
  }
44
- function createTrackingSessionUpsertPayload(trackingParams, input, context) {
45
- return {
46
- session_id: input.sessionId,
47
- visitor_id: input.visitorId ?? null,
48
- gclid: trackingParams.gclid,
49
- fbclid: trackingParams.fbclid,
50
- utm_source: trackingParams.utm_source,
51
- utm_medium: trackingParams.utm_medium,
52
- utm_campaign: trackingParams.utm_campaign,
53
- utm_term: trackingParams.utm_term,
54
- utm_content: trackingParams.utm_content,
55
- first_page: input.firstPage ?? null,
56
- consent_state: input.consentState ?? null,
57
- context
58
- };
79
+ function normalizeTrackingCookieValue(value) {
80
+ return typeof value === "string" && value.length > 0 ? value : null;
59
81
  }
60
- function createTrackingEventCreatePayload(trackingParams, input, context) {
61
- return {
62
- session_id: input.sessionId,
63
- event_type: input.eventType,
64
- gclid: trackingParams.gclid,
65
- fbclid: trackingParams.fbclid,
66
- page_url: input.pageUrl ?? (typeof window === "undefined" ? null : window.location.href),
67
- metadata: input.metadata ?? null,
68
- context
69
- };
82
+ function getTrackingParamsFromCookieReader(readCookie) {
83
+ return TRACKING_PARAM_KEYS.reduce((params, key) => {
84
+ params[key] = normalizeTrackingCookieValue(readCookie(key));
85
+ return params;
86
+ }, createEmptyTrackingParams());
87
+ }
88
+ function getTrackingQueryValues(searchParams) {
89
+ return TRACKING_PARAM_KEYS.reduce((params, key) => {
90
+ const value = searchParams.get(key);
91
+ if (typeof value === "string" && value.trim().length > 0) {
92
+ params[key] = value;
93
+ }
94
+ return params;
95
+ }, {});
96
+ }
97
+ var FALLBACK_STORAGE_PREFIX = "_aranova_track_";
98
+ function fallbackKey(name) {
99
+ return `${FALLBACK_STORAGE_PREFIX}${name}`;
100
+ }
101
+ function persistCookieValue(name, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
102
+ const encoded = encodeURIComponent(value);
103
+ if (typeof document !== "undefined") {
104
+ try {
105
+ document.cookie = `${name}=${encoded}; Max-Age=${maxAgeSeconds}; Path=/; SameSite=Lax`;
106
+ } catch {
107
+ }
108
+ }
109
+ if (typeof window !== "undefined") {
110
+ try {
111
+ window.localStorage.setItem(fallbackKey(name), encoded);
112
+ } catch {
113
+ }
114
+ }
115
+ }
116
+ function readCookieValue(name) {
117
+ if (typeof document !== "undefined") {
118
+ const cookies = document.cookie ? document.cookie.split("; ") : [];
119
+ const match = cookies.find((cookie) => cookie.startsWith(`${name}=`));
120
+ if (match) {
121
+ const [, rawValue = ""] = match.split("=");
122
+ return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
123
+ }
124
+ }
125
+ if (typeof window !== "undefined") {
126
+ try {
127
+ const stored = window.localStorage.getItem(fallbackKey(name));
128
+ if (stored) return normalizeTrackingCookieValue(decodeURIComponent(stored));
129
+ } catch {
130
+ }
131
+ }
132
+ return null;
133
+ }
134
+ function getCookieValueFromDocument(key) {
135
+ return readCookieValue(key);
136
+ }
137
+ function setTrackingCookie(key, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
138
+ persistCookieValue(key, value, maxAgeSeconds);
139
+ }
140
+ function mergeTrackingParams(primary, fallback) {
141
+ return TRACKING_PARAM_KEYS.reduce((merged, key) => {
142
+ merged[key] = primary[key] ?? fallback[key];
143
+ return merged;
144
+ }, createEmptyTrackingParams());
145
+ }
146
+ function persistTrackingParamsFromSearchParams(searchParams, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
147
+ const trackingValues = getTrackingQueryValues(searchParams);
148
+ Object.entries(trackingValues).forEach(([key, value]) => {
149
+ setTrackingCookie(key, value, maxAgeSeconds);
150
+ });
151
+ return trackingValues;
152
+ }
153
+ function captureTrackingParamsFromLocation(url = typeof window === "undefined" ? "" : window.location.href, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
154
+ const resolvedUrl = typeof window === "undefined" ? new URL(url || "https://example.invalid") : new URL(url, window.location.origin);
155
+ persistTrackingParamsFromSearchParams(resolvedUrl.searchParams, maxAgeSeconds);
156
+ return getTrackingParamsFromCookieReader(getCookieValueFromDocument);
70
157
  }
71
158
 
72
159
  // ../tracking-core/src/gtag.ts
@@ -100,17 +187,37 @@ gtag('config', '${gtagId}');
100
187
  }
101
188
  function createConsentRestoreScript() {
102
189
  return `
103
- const consentState = window.localStorage.getItem('consent_state');
104
- if (window.gtag && (consentState === 'granted' || consentState === 'denied')) {
105
- window.gtag('consent', 'update', {
106
- ad_storage: consentState,
107
- ad_user_data: consentState,
108
- ad_personalization: consentState,
109
- analytics_storage: consentState,
110
- });
111
- }
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) {}
112
201
  `.trim();
113
202
  }
203
+ var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
204
+ function isValidSendTo(sendTo) {
205
+ return SEND_TO_RE.test(sendTo);
206
+ }
207
+ function fireGtagConversion(input) {
208
+ if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
209
+ if (!isValidSendTo(input.sendTo)) return false;
210
+ const params = { send_to: input.sendTo };
211
+ if (input.value != null) params.value = input.value;
212
+ if (input.currency) params.currency = input.currency;
213
+ if (input.transactionId) params.transaction_id = input.transactionId;
214
+ try {
215
+ window.gtag("event", "conversion", params);
216
+ return true;
217
+ } catch {
218
+ return false;
219
+ }
220
+ }
114
221
  function createGtagInitScriptMulti(gtagIds) {
115
222
  const safeIds = gtagIds.filter(isValidGtagId);
116
223
  const configs = safeIds.map((id) => `gtag('config', '${id}');`).join("\n");
@@ -123,70 +230,403 @@ ${configs}
123
230
  `.trim();
124
231
  }
125
232
 
126
- // ../tracking-core/src/tracking.ts
127
- var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
128
- var TRACKING_PARAM_KEYS = [
129
- "gclid",
130
- "fbclid",
131
- "utm_source",
132
- "utm_medium",
133
- "utm_campaign",
134
- "utm_term",
135
- "utm_content"
136
- ];
137
- function createEmptyTrackingParams() {
233
+ // ../tracking-core/src/fbq.ts
234
+ var FB_EVENTS_SCRIPT_HOST = "https://connect.facebook.net/en_US/fbevents.js";
235
+ var FBC_COOKIE = "_fbc";
236
+ var FBP_COOKIE = "_fbp";
237
+ var META_PIXEL_ID_PATTERN = /^\d{15,16}$/;
238
+ function isValidMetaPixelId(id) {
239
+ return META_PIXEL_ID_PATTERN.test(id);
240
+ }
241
+ function computeFbSubdomainIndex(hostname) {
242
+ const labels = hostname.split(".").filter(Boolean);
243
+ return Math.max(0, labels.length - 1);
244
+ }
245
+ function buildFbc(fbclid, now, hostname) {
246
+ const host = hostname ?? (typeof window === "undefined" ? "" : window.location.hostname);
247
+ return `fb.${computeFbSubdomainIndex(host)}.${now}.${fbclid}`;
248
+ }
249
+ function getFbcCookie() {
250
+ return readCookieValue(FBC_COOKIE);
251
+ }
252
+ function getFbpCookie() {
253
+ return readCookieValue(FBP_COOKIE);
254
+ }
255
+ function readFbclidFromUrl() {
256
+ if (typeof window === "undefined") return null;
257
+ try {
258
+ const value = new URL(window.location.href).searchParams.get("fbclid");
259
+ return value && value.trim().length > 0 ? value : null;
260
+ } catch {
261
+ return null;
262
+ }
263
+ }
264
+ function captureFbc(now = typeof Date === "undefined" ? 0 : Date.now()) {
265
+ if (typeof window === "undefined") return;
266
+ if (getFbcCookie()) return;
267
+ const fbclid = readFbclidFromUrl() ?? readCookieValue("fbclid");
268
+ if (!fbclid) return;
269
+ persistCookieValue(FBC_COOKIE, buildFbc(fbclid, now), TRACKING_COOKIE_MAX_AGE_SECONDS);
270
+ }
271
+ function fbqStubScript() {
272
+ return `
273
+ !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
274
+ n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
275
+ n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
276
+ t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
277
+ document,'script','${FB_EVENTS_SCRIPT_HOST}');`.trim();
278
+ }
279
+ function createMetaConsentDefaultScript() {
280
+ return `${fbqStubScript()}
281
+ fbq('consent', 'revoke');`;
282
+ }
283
+ function createMetaPixelInitScript(pixelId) {
284
+ if (!isValidMetaPixelId(pixelId)) return "";
285
+ return `fbq('init', '${pixelId}');
286
+ fbq('track', 'PageView');`;
287
+ }
288
+ function createMetaPixelInitScriptMulti(pixelIds) {
289
+ const inits = pixelIds.filter(isValidMetaPixelId).map((id) => `fbq('init', '${id}');`);
290
+ if (inits.length === 0) return "";
291
+ return `${inits.join("\n")}
292
+ fbq('track', 'PageView');`;
293
+ }
294
+ function createMetaConsentRestoreScript() {
295
+ return `
296
+ try {
297
+ var consentState = window.localStorage.getItem('consent_state');
298
+ if (window.fbq && (consentState === 'granted' || consentState === 'denied')) {
299
+ window.fbq('consent', consentState === 'granted' ? 'grant' : 'revoke');
300
+ }
301
+ } catch (e) {}`.trim();
302
+ }
303
+
304
+ // ../tracking-core/src/payloads.ts
305
+ function createTrackingClientContext(surface, input = {}) {
138
306
  return {
139
- gclid: null,
140
- fbclid: null,
141
- utm_source: null,
142
- utm_medium: null,
143
- utm_campaign: null,
144
- utm_term: null,
145
- utm_content: null
307
+ surface,
308
+ sdk_version: input.sdkVersion ?? null,
309
+ package_name: input.packageName ?? null,
310
+ site_origin: input.siteOrigin ?? (typeof window === "undefined" ? null : window.location.origin),
311
+ page_title: input.pageTitle ?? (typeof document === "undefined" ? null : document.title || null),
312
+ referrer: input.referrer ?? (typeof document === "undefined" ? null : document.referrer || null),
313
+ environment: input.environment ?? "production",
314
+ active_gtag_ids: input.activeGtagIds ?? null
146
315
  };
147
316
  }
148
- function normalizeTrackingCookieValue(value) {
149
- return typeof value === "string" && value.length > 0 ? value : null;
317
+ function createTrackingSessionUpsertPayload(trackingParams, input, context) {
318
+ return {
319
+ session_id: input.sessionId,
320
+ visitor_id: input.visitorId ?? null,
321
+ gclid: trackingParams.gclid,
322
+ fbclid: trackingParams.fbclid,
323
+ fbc: getFbcCookie(),
324
+ fbp: getFbpCookie(),
325
+ utm_source: trackingParams.utm_source,
326
+ utm_medium: trackingParams.utm_medium,
327
+ utm_campaign: trackingParams.utm_campaign,
328
+ utm_term: trackingParams.utm_term,
329
+ utm_content: trackingParams.utm_content,
330
+ first_page: input.firstPage ?? null,
331
+ consent_state: input.consentState ?? null,
332
+ context
333
+ };
150
334
  }
151
- function getTrackingParamsFromCookieReader(readCookie) {
152
- return TRACKING_PARAM_KEYS.reduce((params, key) => {
153
- params[key] = normalizeTrackingCookieValue(readCookie(key));
154
- return params;
155
- }, createEmptyTrackingParams());
335
+ function createTrackingEventCreatePayload(trackingParams, input, context) {
336
+ return {
337
+ session_id: input.sessionId,
338
+ event_type: input.eventType,
339
+ gclid: trackingParams.gclid,
340
+ fbclid: trackingParams.fbclid,
341
+ fbc: getFbcCookie(),
342
+ fbp: getFbpCookie(),
343
+ page_url: input.pageUrl ?? (typeof window === "undefined" ? null : window.location.href),
344
+ metadata: input.metadata ?? null,
345
+ context
346
+ };
156
347
  }
157
- function getTrackingQueryValues(searchParams) {
158
- return TRACKING_PARAM_KEYS.reduce((params, key) => {
159
- const value = searchParams.get(key);
160
- if (typeof value === "string" && value.trim().length > 0) {
161
- params[key] = value;
162
- }
163
- return params;
164
- }, {});
348
+
349
+ // ../tracking-core/src/resources/conversion-firing.ts
350
+ var DEDUP_PREFIX = "_aranova_conv_";
351
+ var MAX_PENDING = 100;
352
+ var pendingQueue = [];
353
+ function dedupKey(input) {
354
+ return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
355
+ }
356
+ function alreadyFired(input) {
357
+ if (!input.transactionId || typeof window === "undefined") return false;
358
+ try {
359
+ return window.sessionStorage.getItem(dedupKey(input)) !== null;
360
+ } catch {
361
+ return false;
362
+ }
165
363
  }
166
- function getCookieValueFromDocument(key) {
167
- if (typeof document === "undefined") return null;
168
- const cookies = document.cookie ? document.cookie.split("; ") : [];
169
- const match = cookies.find((cookie) => cookie.startsWith(`${key}=`));
170
- if (!match) return null;
171
- const [, rawValue = ""] = match.split("=");
172
- return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
364
+ function markFired(input) {
365
+ if (!input.transactionId || typeof window === "undefined") return;
366
+ try {
367
+ window.sessionStorage.setItem(dedupKey(input), "1");
368
+ } catch {
369
+ }
173
370
  }
174
- function setTrackingCookie(key, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
175
- if (typeof document === "undefined") return;
176
- const encodedValue = encodeURIComponent(value);
177
- document.cookie = `${key}=${encodedValue}; Max-Age=${maxAgeSeconds}; Path=/; SameSite=Lax`;
371
+ function fireOnce(input) {
372
+ if (alreadyFired(input)) return;
373
+ if (fireGtagConversion(input)) markFired(input);
374
+ }
375
+ function fireConversionWithConsent(input) {
376
+ const state = getConsentState();
377
+ if (state === "denied") return;
378
+ if (state === "pending") {
379
+ if (pendingQueue.length >= MAX_PENDING) pendingQueue.shift();
380
+ pendingQueue.push(input);
381
+ return;
382
+ }
383
+ fireOnce(input);
178
384
  }
179
- function persistTrackingParamsFromSearchParams(searchParams, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
180
- const trackingValues = getTrackingQueryValues(searchParams);
181
- Object.entries(trackingValues).forEach(([key, value]) => {
182
- setTrackingCookie(key, value, maxAgeSeconds);
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
+
394
+ // ../tracking-core/src/resources/conversion-config.ts
395
+ function isStringMap(value) {
396
+ return typeof value === "object" && value !== null && Object.values(value).every((v) => typeof v === "string");
397
+ }
398
+ function parseFiring(value) {
399
+ if (!value || typeof value !== "object") return null;
400
+ const f = value;
401
+ if (typeof f.send_to !== "string") return null;
402
+ return {
403
+ send_to: f.send_to,
404
+ value_cents: typeof f.value_cents === "number" ? f.value_cents : null,
405
+ currency: typeof f.currency === "string" ? f.currency : null
406
+ };
407
+ }
408
+ function parseTrigger(value) {
409
+ if (!value || typeof value !== "object") return null;
410
+ const t = value;
411
+ if (typeof t.event_type !== "string") return null;
412
+ const spec = { event_type: t.event_type };
413
+ if (typeof t.threshold_percent === "number") spec.threshold_percent = t.threshold_percent;
414
+ if (typeof t.threshold_seconds === "number") spec.threshold_seconds = t.threshold_seconds;
415
+ if (typeof t.page_threshold === "number") spec.page_threshold = t.page_threshold;
416
+ if (typeof t.page_name === "string") spec.page_name = t.page_name;
417
+ return spec;
418
+ }
419
+ function parseConversionConfig(raw) {
420
+ if (!raw || typeof raw !== "object") return null;
421
+ const obj = raw;
422
+ const servicesRaw = Array.isArray(obj.services) ? obj.services : [];
423
+ const services = servicesRaw.flatMap((entry) => {
424
+ if (!entry || typeof entry !== "object") return [];
425
+ const s = entry;
426
+ if (typeof s.key !== "string") return [];
427
+ return [
428
+ {
429
+ key: s.key,
430
+ label: typeof s.label === "string" ? s.label : void 0,
431
+ firing: parseFiring(s.firing)
432
+ }
433
+ ];
183
434
  });
184
- return trackingValues;
435
+ const goalsRaw = Array.isArray(obj.goals) ? obj.goals : null;
436
+ const goals = goalsRaw ? goalsRaw.flatMap((entry) => {
437
+ if (!entry || typeof entry !== "object") return [];
438
+ const g = entry;
439
+ if (typeof g.key !== "string") return [];
440
+ return [
441
+ {
442
+ key: g.key,
443
+ label: typeof g.label === "string" ? g.label : void 0,
444
+ kind: g.kind === "event" ? "event" : "sale",
445
+ trigger: parseTrigger(g.trigger),
446
+ firing: parseFiring(g.firing)
447
+ }
448
+ ];
449
+ }) : services.map((s) => ({
450
+ key: s.key,
451
+ label: s.label,
452
+ kind: "sale",
453
+ trigger: null,
454
+ firing: s.firing
455
+ }));
456
+ return {
457
+ schema_version: typeof obj.schema_version === "number" ? obj.schema_version : 1,
458
+ config_version: typeof obj.config_version === "number" ? obj.config_version : 0,
459
+ business_id: typeof obj.business_id === "string" ? obj.business_id : void 0,
460
+ customer_id: typeof obj.customer_id === "string" ? obj.customer_id : null,
461
+ environment: typeof obj.environment === "string" ? obj.environment : void 0,
462
+ gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
463
+ meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
464
+ services,
465
+ goals
466
+ };
185
467
  }
186
- function captureTrackingParamsFromLocation(url = typeof window === "undefined" ? "" : window.location.href, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
187
- const resolvedUrl = typeof window === "undefined" ? new URL(url || "https://example.invalid") : new URL(url, window.location.origin);
188
- persistTrackingParamsFromSearchParams(resolvedUrl.searchParams, maxAgeSeconds);
189
- return getTrackingParamsFromCookieReader(getCookieValueFromDocument);
468
+ var CACHE_PREFIX = "_aranova_cfg_";
469
+ function cacheKey(url) {
470
+ return `${CACHE_PREFIX}${url}`;
471
+ }
472
+ function readCache(url) {
473
+ if (typeof window === "undefined") return null;
474
+ try {
475
+ const raw = window.sessionStorage.getItem(cacheKey(url));
476
+ if (!raw) return null;
477
+ const parsed = JSON.parse(raw);
478
+ const config = parseConversionConfig(parsed.config);
479
+ if (!config) return null;
480
+ return {
481
+ etag: typeof parsed.etag === "string" ? parsed.etag : null,
482
+ config
483
+ };
484
+ } catch {
485
+ return null;
486
+ }
487
+ }
488
+ function writeCache(url, entry) {
489
+ if (typeof window === "undefined") return;
490
+ try {
491
+ window.sessionStorage.setItem(cacheKey(url), JSON.stringify(entry));
492
+ } catch {
493
+ }
494
+ }
495
+ function resolveConversionConfig(options) {
496
+ const cached = readCache(options.cdnUrl);
497
+ let current = cached?.config ?? options.baked ?? null;
498
+ let etag = cached?.etag ?? null;
499
+ const goalsByKey = /* @__PURE__ */ new Map();
500
+ function rebuildIndex() {
501
+ goalsByKey.clear();
502
+ for (const goal of current?.goals ?? []) {
503
+ goalsByKey.set(goal.key, goal);
504
+ }
505
+ }
506
+ function adopt(next, nextEtag) {
507
+ if (!next) return;
508
+ if (current && next.config_version <= current.config_version) return;
509
+ current = next;
510
+ etag = nextEtag;
511
+ rebuildIndex();
512
+ writeCache(options.cdnUrl, { etag, config: next });
513
+ }
514
+ async function revalidate() {
515
+ if (typeof window === "undefined") return;
516
+ try {
517
+ const doFetch = options.fetchImpl ?? globalThis.fetch;
518
+ if (!doFetch) return;
519
+ const headers = {};
520
+ if (etag) headers["If-None-Match"] = etag;
521
+ const response = await doFetch(options.cdnUrl, {
522
+ method: "GET",
523
+ headers
524
+ });
525
+ if (response.status === 304 || !response.ok) return;
526
+ adopt(parseConversionConfig(await response.json()), response.headers.get("ETag"));
527
+ } catch {
528
+ }
529
+ }
530
+ rebuildIndex();
531
+ void revalidate();
532
+ return {
533
+ getFiring: (key) => goalsByKey.get(key)?.firing ?? null,
534
+ getGoal: (key) => goalsByKey.get(key) ?? null,
535
+ listGoals: () => [...goalsByKey.values()],
536
+ current: () => current,
537
+ revalidate
538
+ };
539
+ }
540
+
541
+ // ../tracking-core/src/resources/sales/money.ts
542
+ var MINOR_UNIT_EXPONENT = {
543
+ USD: 2,
544
+ CAD: 2
545
+ };
546
+ function exponentFor(currency) {
547
+ return MINOR_UNIT_EXPONENT[currency] ?? 2;
548
+ }
549
+ function toMinor(amount, currency) {
550
+ return Math.round(amount * 10 ** exponentFor(currency));
551
+ }
552
+ function fromMinor(cents, currency) {
553
+ return cents / 10 ** exponentFor(currency);
554
+ }
555
+ function formatMoney(cents, currency, locale) {
556
+ return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
557
+ fromMinor(cents, currency)
558
+ );
559
+ }
560
+ function formatDateInTz(iso, timeZone, opts, locale) {
561
+ const date = new Date(iso);
562
+ if (Number.isNaN(date.getTime())) return iso;
563
+ return new Intl.DateTimeFormat(locale, {
564
+ year: "numeric",
565
+ month: "short",
566
+ day: "2-digit",
567
+ hour: "2-digit",
568
+ minute: "2-digit",
569
+ ...opts,
570
+ timeZone
571
+ }).format(date);
572
+ }
573
+
574
+ // ../tracking-core/src/resources/conversion-autofire.ts
575
+ function thresholdMet(goal, eventType, metadata) {
576
+ const t = goal.trigger;
577
+ if (!t || t.event_type !== eventType) return false;
578
+ switch (eventType) {
579
+ case "scroll_depth":
580
+ return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
581
+ case "time_on_site":
582
+ return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
583
+ case "multi_page_session":
584
+ return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
585
+ case "specific_page_visit":
586
+ return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
587
+ case "page_view":
588
+ case "form_start":
589
+ return true;
590
+ // no threshold — fire whenever the detector emits
591
+ default:
592
+ return false;
593
+ }
594
+ }
595
+ function currentPath() {
596
+ return typeof window === "undefined" ? "" : window.location.pathname;
597
+ }
598
+ function createConversionAutoFire(store) {
599
+ return {
600
+ onAutomaticEvent(eventType, metadata) {
601
+ for (const goal of store.listGoals()) {
602
+ if (goal.kind !== "event" || !goal.firing) continue;
603
+ if (!thresholdMet(goal, eventType, metadata)) continue;
604
+ const firing = goal.firing;
605
+ const cents = firing.value_cents ?? null;
606
+ const currency = firing.currency ?? null;
607
+ fireConversionWithConsent({
608
+ sendTo: firing.send_to,
609
+ value: cents != null && currency ? fromMinor(cents, currency) : null,
610
+ currency,
611
+ // Page-scoped txn id → fire once per (goal, path) per session; engagement conversions
612
+ // shouldn't re-fire as the visitor scrolls back and forth or re-enters a page.
613
+ transactionId: `auto:${goal.key}:${currentPath()}`
614
+ });
615
+ }
616
+ }
617
+ };
618
+ }
619
+ function withConversionAutoFire(client, autoFire) {
620
+ return {
621
+ ...client,
622
+ trackEvent: (input) => {
623
+ client.trackEvent(input);
624
+ try {
625
+ autoFire.onAutomaticEvent(input.eventType, input.metadata ?? {});
626
+ } catch {
627
+ }
628
+ }
629
+ };
190
630
  }
191
631
 
192
632
  // ../tracking-core/src/session.ts
@@ -479,11 +919,22 @@ function createTrackingClient(config) {
479
919
  let queue = [];
480
920
  let flushTimer = null;
481
921
  let firstPage = null;
922
+ let initialParams = createEmptyTrackingParams();
482
923
  let destroyed = false;
483
924
  const visitorId = getVisitorId();
484
925
  const initialSession = getOrRotateSessionId();
485
926
  let sessionId = initialSession.id;
486
- if (typeof window !== "undefined") firstPage = window.location.href;
927
+ if (typeof window !== "undefined") {
928
+ firstPage = window.location.href;
929
+ try {
930
+ initialParams = captureTrackingParamsFromLocation();
931
+ } catch {
932
+ }
933
+ try {
934
+ captureFbc();
935
+ } catch {
936
+ }
937
+ }
487
938
  function enqueueHeartbeat() {
488
939
  const metadata = buildHeartbeatMetadata(
489
940
  config.surface,
@@ -508,7 +959,7 @@ function createTrackingClient(config) {
508
959
  enqueueHeartbeat();
509
960
  }
510
961
  sessionId = rotated.id;
511
- const params = readTrackingParams();
962
+ const params = mergeTrackingParams(readTrackingParams(), initialParams);
512
963
  const context = buildContext(
513
964
  config.surface,
514
965
  sdkVersion,
@@ -521,6 +972,8 @@ function createTrackingClient(config) {
521
972
  visitor_id: visitorId,
522
973
  gclid: params.gclid,
523
974
  fbclid: params.fbclid,
975
+ fbc: getFbcCookie(),
976
+ fbp: getFbpCookie(),
524
977
  utm_source: params.utm_source,
525
978
  utm_medium: params.utm_medium,
526
979
  utm_campaign: params.utm_campaign,
@@ -912,7 +1365,7 @@ function attachScrollDepth(client, config) {
912
1365
  }
913
1366
  const thresholds = new Set(config.thresholds);
914
1367
  let firedForPath = /* @__PURE__ */ new Set();
915
- let currentPath = window.location.pathname;
1368
+ let currentPath2 = window.location.pathname;
916
1369
  let rafId = null;
917
1370
  function getScrollPercent() {
918
1371
  const doc = document.documentElement;
@@ -931,7 +1384,7 @@ function attachScrollDepth(client, config) {
931
1384
  eventType: "scroll_depth",
932
1385
  metadata: {
933
1386
  depth_percent: threshold,
934
- page: { path: currentPath }
1387
+ page: { path: currentPath2 }
935
1388
  },
936
1389
  pageUrl: window.location.href,
937
1390
  occurredAt: null
@@ -948,8 +1401,8 @@ function attachScrollDepth(client, config) {
948
1401
  }
949
1402
  function resetIfPathChanged() {
950
1403
  const newPath = window.location.pathname;
951
- if (newPath === currentPath) return;
952
- currentPath = newPath;
1404
+ if (newPath === currentPath2) return;
1405
+ currentPath2 = newPath;
953
1406
  firedForPath = /* @__PURE__ */ new Set();
954
1407
  setTimeout(checkThresholds, 0);
955
1408
  }
@@ -985,7 +1438,7 @@ function attachFormStart(client, config) {
985
1438
  }
986
1439
  const selector = config.selector ?? "form";
987
1440
  let firedForms = /* @__PURE__ */ new Set();
988
- let currentPath = window.location.pathname;
1441
+ let currentPath2 = window.location.pathname;
989
1442
  function getFormKey(form) {
990
1443
  if (form.id) return `id:${form.id}`;
991
1444
  const explicitAction = form.getAttribute("action");
@@ -1016,8 +1469,8 @@ function attachFormStart(client, config) {
1016
1469
  }
1017
1470
  function resetIfPathChanged() {
1018
1471
  const newPath = window.location.pathname;
1019
- if (newPath === currentPath) return;
1020
- currentPath = newPath;
1472
+ if (newPath === currentPath2) return;
1473
+ currentPath2 = newPath;
1021
1474
  firedForms = /* @__PURE__ */ new Set();
1022
1475
  }
1023
1476
  const originalPushState = history.pushState.bind(history);
@@ -1096,21 +1549,64 @@ async function salesRequest(config, method, path, body) {
1096
1549
  }
1097
1550
 
1098
1551
  // ../tracking-core/src/resources/sales/client.ts
1552
+ function fireRecordedConversions(firing, input, recorded, sale, currency) {
1553
+ if (!firing) return;
1554
+ const txnBase = input.external_id ?? sale.id;
1555
+ for (const item of recorded) {
1556
+ if (!item.service) continue;
1557
+ const config = firing.getFiring(item.service);
1558
+ if (!config) continue;
1559
+ const cents = item.amount_cents ?? config.value_cents ?? null;
1560
+ fireConversionWithConsent({
1561
+ sendTo: config.send_to,
1562
+ value: cents != null ? fromMinor(cents, currency) : null,
1563
+ currency: config.currency ?? currency,
1564
+ transactionId: `${txnBase}:${item.service}`
1565
+ });
1566
+ }
1567
+ }
1099
1568
  function createSalesClient(config) {
1100
- return {
1101
- async record(input) {
1102
- const currency = input.currency ?? config.defaultCurrency;
1103
- if (!currency) {
1104
- throw new Error(
1105
- "record: `currency` is required (pass it on the sale or set config.defaultCurrency)"
1106
- );
1569
+ async function record(input) {
1570
+ const currency = input.currency ?? config.defaultCurrency;
1571
+ if (!currency) {
1572
+ throw new Error(
1573
+ "record: `currency` is required (pass it on the sale or set config.defaultCurrency)"
1574
+ );
1575
+ }
1576
+ const body = {
1577
+ ...input,
1578
+ currency,
1579
+ occurred_at: input.occurred_at ?? (/* @__PURE__ */ new Date()).toISOString()
1580
+ };
1581
+ const sale = await salesRequest(config, "POST", "/sales", body);
1582
+ const recorded = input.services?.length ? input.services.map((s) => ({
1583
+ service: s.service,
1584
+ amount_cents: s.amount_cents
1585
+ })) : [
1586
+ {
1587
+ service: input.service,
1588
+ amount_cents: input.amount_total_cents ?? null
1107
1589
  }
1108
- const body = {
1109
- ...input,
1590
+ ];
1591
+ fireRecordedConversions(config.firing, input, recorded, sale, currency);
1592
+ return sale;
1593
+ }
1594
+ return {
1595
+ record,
1596
+ // recordSale is the intent-revealing alias — same behavior, clearer call site.
1597
+ recordSale: record,
1598
+ trackConversion(key, options) {
1599
+ const firing = config.firing?.getFiring(key);
1600
+ if (!firing) return;
1601
+ const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
1602
+ const cents = firing.value_cents ?? null;
1603
+ const value = options?.value ?? (cents != null && currency ? fromMinor(cents, currency) : null);
1604
+ fireConversionWithConsent({
1605
+ sendTo: firing.send_to,
1606
+ value,
1110
1607
  currency,
1111
- occurred_at: input.occurred_at ?? (/* @__PURE__ */ new Date()).toISOString()
1112
- };
1113
- return salesRequest(config, "POST", "/sales", body);
1608
+ transactionId: options?.transactionId ?? null
1609
+ });
1114
1610
  },
1115
1611
  async list(query) {
1116
1612
  const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
@@ -1204,39 +1700,6 @@ function createSalesClient(config) {
1204
1700
  };
1205
1701
  }
1206
1702
 
1207
- // ../tracking-core/src/resources/sales/money.ts
1208
- var MINOR_UNIT_EXPONENT = {
1209
- USD: 2,
1210
- CAD: 2
1211
- };
1212
- function exponentFor(currency) {
1213
- return MINOR_UNIT_EXPONENT[currency] ?? 2;
1214
- }
1215
- function toMinor(amount, currency) {
1216
- return Math.round(amount * 10 ** exponentFor(currency));
1217
- }
1218
- function fromMinor(cents, currency) {
1219
- return cents / 10 ** exponentFor(currency);
1220
- }
1221
- function formatMoney(cents, currency, locale) {
1222
- return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
1223
- fromMinor(cents, currency)
1224
- );
1225
- }
1226
- function formatDateInTz(iso, timeZone, opts, locale) {
1227
- const date = new Date(iso);
1228
- if (Number.isNaN(date.getTime())) return iso;
1229
- return new Intl.DateTimeFormat(locale, {
1230
- year: "numeric",
1231
- month: "short",
1232
- day: "2-digit",
1233
- hour: "2-digit",
1234
- minute: "2-digit",
1235
- ...opts,
1236
- timeZone
1237
- }).format(date);
1238
- }
1239
-
1240
1703
  // ../tracking-core/src/resources/sales/schema.ts
1241
1704
  import { z as z11 } from "zod";
1242
1705
  var SUPPORTED_CURRENCIES = ["USD", "CAD"];
@@ -1639,26 +2102,61 @@ var ANIMATION_KEYFRAMES = `
1639
2102
  }
1640
2103
  `;
1641
2104
 
1642
- // src/GoogleAdsTracking.tsx
2105
+ // src/AdPlatformTracking.tsx
1643
2106
  import Script from "next/script";
1644
2107
  import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2108
+ function AdPlatformTracking({
2109
+ gtagId,
2110
+ gtagIds,
2111
+ metaPixelId,
2112
+ metaPixelIds
2113
+ }) {
2114
+ const gtagAll = gtagIds ? Object.values(gtagIds).filter((id) => id != null) : gtagId ? [gtagId] : [];
2115
+ const metaAll = metaPixelIds ? Object.values(metaPixelIds).filter((id) => id != null) : metaPixelId ? [metaPixelId] : [];
2116
+ const gtagLoaderId = gtagAll[0];
2117
+ const gtagInitScript = gtagAll.length === 1 ? createGtagInitScript(gtagAll[0]) : createGtagInitScriptMulti(gtagAll);
2118
+ const metaInitScript = metaAll.length === 1 ? createMetaPixelInitScript(metaAll[0]) : createMetaPixelInitScriptMulti(metaAll);
2119
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
2120
+ gtagLoaderId ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
2121
+ /* @__PURE__ */ jsx2(Script, { id: "consent-default", strategy: "beforeInteractive", children: createConsentDefaultScript() }),
2122
+ /* @__PURE__ */ jsx2(
2123
+ Script,
2124
+ {
2125
+ src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(gtagLoaderId)}`,
2126
+ strategy: "afterInteractive"
2127
+ }
2128
+ ),
2129
+ /* @__PURE__ */ jsx2(Script, { id: "gtag-init", strategy: "afterInteractive", children: gtagInitScript }),
2130
+ /* @__PURE__ */ jsx2(Script, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
2131
+ ] }) : null,
2132
+ metaAll.length > 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
2133
+ /* @__PURE__ */ jsx2(Script, { id: "meta-pixel-base", strategy: "afterInteractive", children: createMetaConsentDefaultScript() }),
2134
+ /* @__PURE__ */ jsx2(Script, { id: "meta-pixel-init", strategy: "afterInteractive", children: metaInitScript }),
2135
+ /* @__PURE__ */ jsx2(Script, { id: "meta-pixel-consent-restore", strategy: "afterInteractive", children: createMetaConsentRestoreScript() })
2136
+ ] }) : null
2137
+ ] });
2138
+ }
2139
+
2140
+ // src/GoogleAdsTracking.tsx
2141
+ import Script2 from "next/script";
2142
+ import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1645
2143
  function GoogleAdsTracking(props) {
1646
2144
  const { gtagId, gtagIds } = props;
1647
2145
  const allIds = gtagIds ? Object.values(gtagIds).filter((id) => id != null) : gtagId ? [gtagId] : [];
1648
2146
  if (allIds.length === 0) return null;
1649
2147
  const loaderId = allIds[0];
1650
2148
  const initScript = allIds.length === 1 ? createGtagInitScript(loaderId) : createGtagInitScriptMulti(allIds);
1651
- return /* @__PURE__ */ jsxs2(Fragment2, { children: [
1652
- /* @__PURE__ */ jsx2(Script, { id: "consent-default", strategy: "beforeInteractive", children: createConsentDefaultScript() }),
1653
- /* @__PURE__ */ jsx2(
1654
- Script,
2149
+ return /* @__PURE__ */ jsxs3(Fragment3, { children: [
2150
+ /* @__PURE__ */ jsx3(Script2, { id: "consent-default", strategy: "beforeInteractive", children: createConsentDefaultScript() }),
2151
+ /* @__PURE__ */ jsx3(
2152
+ Script2,
1655
2153
  {
1656
2154
  src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(loaderId)}`,
1657
2155
  strategy: "afterInteractive"
1658
2156
  }
1659
2157
  ),
1660
- /* @__PURE__ */ jsx2(Script, { id: "gtag-init", strategy: "afterInteractive", children: initScript }),
1661
- /* @__PURE__ */ jsx2(Script, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
2158
+ /* @__PURE__ */ jsx3(Script2, { id: "gtag-init", strategy: "afterInteractive", children: initScript }),
2159
+ /* @__PURE__ */ jsx3(Script2, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
1662
2160
  ] });
1663
2161
  }
1664
2162
 
@@ -1666,7 +2164,7 @@ function GoogleAdsTracking(props) {
1666
2164
  import { usePathname, useSearchParams } from "next/navigation";
1667
2165
 
1668
2166
  // package.json
1669
- var version = "0.12.2";
2167
+ var version = "0.14.0";
1670
2168
 
1671
2169
  // src/factory.tsx
1672
2170
  import { createContext as createContext2, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo2, useRef } from "react";
@@ -1680,7 +2178,7 @@ import {
1680
2178
  useMemo,
1681
2179
  useState as useState3
1682
2180
  } from "react";
1683
- import { jsx as jsx3 } from "react/jsx-runtime";
2181
+ import { jsx as jsx4 } from "react/jsx-runtime";
1684
2182
  var _phoneConfigContext;
1685
2183
  function phoneConfigContext() {
1686
2184
  return _phoneConfigContext ?? (_phoneConfigContext = createContext(null));
@@ -1690,7 +2188,7 @@ function PhoneConfigProvider({
1690
2188
  children
1691
2189
  }) {
1692
2190
  const Ctx = phoneConfigContext();
1693
- return /* @__PURE__ */ jsx3(Ctx.Provider, { value, children });
2191
+ return /* @__PURE__ */ jsx4(Ctx.Provider, { value, children });
1694
2192
  }
1695
2193
  function usePhoneConfig() {
1696
2194
  const ctx = useContext(phoneConfigContext());
@@ -1750,7 +2248,7 @@ var PhoneField = forwardRef(function PhoneField2({ country, value, defaultValue,
1750
2248
  onChange?.(event);
1751
2249
  };
1752
2250
  const shown = isControlled ? formatPhoneAsTyped(value, resolvedCountry) : internal;
1753
- return /* @__PURE__ */ jsx3(
2251
+ return /* @__PURE__ */ jsx4(
1754
2252
  "input",
1755
2253
  {
1756
2254
  ...rest,
@@ -1765,9 +2263,9 @@ var PhoneField = forwardRef(function PhoneField2({ country, value, defaultValue,
1765
2263
  });
1766
2264
 
1767
2265
  // src/factory.tsx
1768
- import { jsx as jsx4 } from "react/jsx-runtime";
2266
+ import { jsx as jsx5 } from "react/jsx-runtime";
1769
2267
  function createTracking(options) {
1770
- const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone } = options;
2268
+ const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone, conversionConfig } = options;
1771
2269
  if (!apiKey || !endpoint) {
1772
2270
  if (apiKey || endpoint) {
1773
2271
  console.warn(
@@ -1783,7 +2281,7 @@ function createTracking(options) {
1783
2281
  getVisitorId: () => ""
1784
2282
  };
1785
2283
  return {
1786
- TrackingProvider: ({ children }) => /* @__PURE__ */ jsx4(PhoneConfigProvider, { value: phone ?? null, children }),
2284
+ TrackingProvider: ({ children }) => /* @__PURE__ */ jsx5(PhoneConfigProvider, { value: phone ?? null, children }),
1787
2285
  useTracking: () => noopClient
1788
2286
  };
1789
2287
  }
@@ -1811,6 +2309,17 @@ function createTracking(options) {
1811
2309
  ),
1812
2310
  []
1813
2311
  );
2312
+ const conversionStore = useMemo2(
2313
+ () => conversionConfig ? resolveConversionConfig({
2314
+ cdnUrl: conversionConfig.cdnUrl,
2315
+ baked: conversionConfig.baked
2316
+ }) : null,
2317
+ []
2318
+ );
2319
+ const wrapClient = useMemo2(() => {
2320
+ const autoFire = conversionStore ? createConversionAutoFire(conversionStore) : null;
2321
+ return (c) => autoFire ? withConversionAutoFire(c, autoFire) : c;
2322
+ }, [conversionStore]);
1814
2323
  useEffect3(() => {
1815
2324
  const rawClient = getOrCreateTrackingClient({
1816
2325
  apiKey,
@@ -1822,7 +2331,7 @@ function createTracking(options) {
1822
2331
  activeGtagIds: gtagIds,
1823
2332
  debug
1824
2333
  });
1825
- fireManualPageView(rawClient);
2334
+ fireManualPageView(wrapClient(rawClient));
1826
2335
  }, [pathname, searchParams]);
1827
2336
  const firedPagesRef = useRef(/* @__PURE__ */ new Set());
1828
2337
  useEffect3(() => {
@@ -1837,14 +2346,18 @@ function createTracking(options) {
1837
2346
  activeGtagIds: gtagIds,
1838
2347
  debug
1839
2348
  });
2349
+ const detectorClient = wrapClient(rawClient);
1840
2350
  for (const { name, pathPattern } of specificPageVisitConfig.pages) {
1841
2351
  if (!pathPattern.test(pathname)) continue;
1842
2352
  const key = `${name}:${pathname}`;
1843
2353
  if (firedPagesRef.current.has(key)) continue;
1844
2354
  firedPagesRef.current.add(key);
1845
- rawClient.trackEvent({
2355
+ detectorClient.trackEvent({
1846
2356
  eventType: "specific_page_visit",
1847
- metadata: { page_name: name, page: { path: pathname } },
2357
+ metadata: {
2358
+ page_name: name,
2359
+ page: { path: pathname }
2360
+ },
1848
2361
  pageUrl: null,
1849
2362
  occurredAt: null
1850
2363
  });
@@ -1861,7 +2374,7 @@ function createTracking(options) {
1861
2374
  activeGtagIds: gtagIds,
1862
2375
  debug
1863
2376
  });
1864
- return attachBfcacheRestore(rawClient);
2377
+ return attachBfcacheRestore(wrapClient(rawClient));
1865
2378
  }, []);
1866
2379
  useEffect3(() => {
1867
2380
  if (!timeOnSiteConfig) return;
@@ -1875,7 +2388,7 @@ function createTracking(options) {
1875
2388
  activeGtagIds: gtagIds,
1876
2389
  debug
1877
2390
  });
1878
- return attachTimeOnSite(rawClient, timeOnSiteConfig);
2391
+ return attachTimeOnSite(wrapClient(rawClient), timeOnSiteConfig);
1879
2392
  }, []);
1880
2393
  const multiPageSessionConfig = triggers.automatic.multi_page_session ?? null;
1881
2394
  const mpsLastPathRef = useRef(null);
@@ -1913,7 +2426,7 @@ function createTracking(options) {
1913
2426
  activeGtagIds: gtagIds,
1914
2427
  debug
1915
2428
  });
1916
- rawClient.trackEvent({
2429
+ wrapClient(rawClient).trackEvent({
1917
2430
  eventType: "multi_page_session",
1918
2431
  metadata: {
1919
2432
  page_count: paths.size,
@@ -1938,13 +2451,14 @@ function createTracking(options) {
1938
2451
  activeGtagIds: gtagIds,
1939
2452
  debug
1940
2453
  });
2454
+ const detectorClient = wrapClient(rawClient);
1941
2455
  const scrollDepth = triggers.automatic.scroll_depth;
1942
2456
  if (scrollDepth) {
1943
- detachers.push(attachScrollDepth(rawClient, scrollDepth));
2457
+ detachers.push(attachScrollDepth(detectorClient, scrollDepth));
1944
2458
  }
1945
2459
  const formStart = triggers.automatic.form_start;
1946
2460
  if (formStart) {
1947
- detachers.push(attachFormStart(rawClient, formStart));
2461
+ detachers.push(attachFormStart(detectorClient, formStart));
1948
2462
  }
1949
2463
  return () => {
1950
2464
  for (let i = detachers.length - 1; i >= 0; i--) {
@@ -1952,7 +2466,7 @@ function createTracking(options) {
1952
2466
  }
1953
2467
  };
1954
2468
  }, []);
1955
- return /* @__PURE__ */ jsx4(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ jsx4(PhoneConfigProvider, { value: phone ?? null, children }) });
2469
+ return /* @__PURE__ */ jsx5(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ jsx5(PhoneConfigProvider, { value: phone ?? null, children }) });
1956
2470
  }
1957
2471
  function useTracking() {
1958
2472
  const client = useContext2(TrackingContext);
@@ -1966,6 +2480,7 @@ function createTracking(options) {
1966
2480
  return { TrackingProvider, useTracking };
1967
2481
  }
1968
2482
  export {
2483
+ AdPlatformTracking,
1969
2484
  AranovaApiError,
1970
2485
  ConsentBanner,
1971
2486
  DEFAULT_PHONE_COUNTRY,
@@ -1991,6 +2506,7 @@ export {
1991
2506
  parsePhone,
1992
2507
  phoneField,
1993
2508
  resetConsent,
2509
+ resolveConversionConfig,
1994
2510
  saleCreateSchema,
1995
2511
  saleItemSchema,
1996
2512
  saleServiceSchema,