@aranova/tracking-next 0.13.0 → 0.14.1

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,
@@ -29,6 +36,14 @@ function setConsentState(state) {
29
36
  window.gtag("consent", "update", buildConsentPayload(state));
30
37
  if (typeof window.fbq === "function")
31
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
+ }
32
47
  }
33
48
  function resetConsent() {
34
49
  if (typeof window === "undefined") return;
@@ -185,6 +200,24 @@ try {
185
200
  } catch (e) {}
186
201
  `.trim();
187
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
+ }
188
221
  function createGtagInitScriptMulti(gtagIds) {
189
222
  const safeIds = gtagIds.filter(isValidGtagId);
190
223
  const configs = safeIds.map((id) => `gtag('config', '${id}');`).join("\n");
@@ -313,6 +346,329 @@ function createTrackingEventCreatePayload(trackingParams, input, context) {
313
346
  };
314
347
  }
315
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
+ }
363
+ }
364
+ function markFired(input) {
365
+ if (!input.transactionId || typeof window === "undefined") return;
366
+ try {
367
+ window.sessionStorage.setItem(dedupKey(input), "1");
368
+ } catch {
369
+ }
370
+ }
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);
384
+ }
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
+ ];
434
+ });
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
+ };
467
+ }
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
+ const resolveListeners = /* @__PURE__ */ new Set();
501
+ function rebuildIndex() {
502
+ goalsByKey.clear();
503
+ for (const goal of current?.goals ?? []) {
504
+ goalsByKey.set(goal.key, goal);
505
+ }
506
+ }
507
+ function notifyResolved() {
508
+ const listeners = [...resolveListeners];
509
+ resolveListeners.clear();
510
+ for (const listener of listeners) {
511
+ try {
512
+ listener();
513
+ } catch {
514
+ }
515
+ }
516
+ }
517
+ function adopt(next, nextEtag) {
518
+ if (!next) return;
519
+ if (current && next.config_version <= current.config_version) return;
520
+ const wasEmpty = current === null;
521
+ current = next;
522
+ etag = nextEtag;
523
+ rebuildIndex();
524
+ writeCache(options.cdnUrl, { etag, config: next });
525
+ if (wasEmpty) notifyResolved();
526
+ }
527
+ async function revalidate() {
528
+ if (typeof window === "undefined") return;
529
+ try {
530
+ const doFetch = options.fetchImpl ?? globalThis.fetch;
531
+ if (!doFetch) return;
532
+ const headers = {};
533
+ if (etag) headers["If-None-Match"] = etag;
534
+ const response = await doFetch(options.cdnUrl, {
535
+ method: "GET",
536
+ headers
537
+ });
538
+ if (response.status === 304 || !response.ok) return;
539
+ adopt(parseConversionConfig(await response.json()), response.headers.get("ETag"));
540
+ } catch {
541
+ }
542
+ }
543
+ rebuildIndex();
544
+ void revalidate();
545
+ return {
546
+ getFiring: (key) => goalsByKey.get(key)?.firing ?? null,
547
+ getGoal: (key) => goalsByKey.get(key) ?? null,
548
+ listGoals: () => [...goalsByKey.values()],
549
+ current: () => current,
550
+ isReady: () => current !== null,
551
+ onResolve: (listener) => {
552
+ if (current !== null) {
553
+ listener();
554
+ return () => {
555
+ };
556
+ }
557
+ resolveListeners.add(listener);
558
+ return () => resolveListeners.delete(listener);
559
+ },
560
+ revalidate
561
+ };
562
+ }
563
+
564
+ // ../tracking-core/src/resources/sales/money.ts
565
+ var MINOR_UNIT_EXPONENT = {
566
+ USD: 2,
567
+ CAD: 2
568
+ };
569
+ function exponentFor(currency) {
570
+ return MINOR_UNIT_EXPONENT[currency] ?? 2;
571
+ }
572
+ function toMinor(amount, currency) {
573
+ return Math.round(amount * 10 ** exponentFor(currency));
574
+ }
575
+ function fromMinor(cents, currency) {
576
+ return cents / 10 ** exponentFor(currency);
577
+ }
578
+ function formatMoney(cents, currency, locale) {
579
+ return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
580
+ fromMinor(cents, currency)
581
+ );
582
+ }
583
+ function formatDateInTz(iso, timeZone, opts, locale) {
584
+ const date = new Date(iso);
585
+ if (Number.isNaN(date.getTime())) return iso;
586
+ return new Intl.DateTimeFormat(locale, {
587
+ year: "numeric",
588
+ month: "short",
589
+ day: "2-digit",
590
+ hour: "2-digit",
591
+ minute: "2-digit",
592
+ ...opts,
593
+ timeZone
594
+ }).format(date);
595
+ }
596
+
597
+ // ../tracking-core/src/resources/conversion-autofire.ts
598
+ function thresholdMet(goal, eventType, metadata) {
599
+ const t = goal.trigger;
600
+ if (!t || t.event_type !== eventType) return false;
601
+ switch (eventType) {
602
+ case "scroll_depth":
603
+ return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
604
+ case "time_on_site":
605
+ return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
606
+ case "multi_page_session":
607
+ return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
608
+ case "specific_page_visit":
609
+ return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
610
+ case "page_view":
611
+ case "form_start":
612
+ return true;
613
+ // no threshold — fire whenever the detector emits
614
+ default:
615
+ return false;
616
+ }
617
+ }
618
+ function currentPath() {
619
+ return typeof window === "undefined" ? "" : window.location.pathname;
620
+ }
621
+ var MAX_BUFFERED_EVENTS = 50;
622
+ function createConversionAutoFire(store) {
623
+ const pending = [];
624
+ let subscribed = false;
625
+ function fireMatching(eventType, metadata) {
626
+ for (const goal of store.listGoals()) {
627
+ if (goal.kind !== "event" || !goal.firing) continue;
628
+ if (!thresholdMet(goal, eventType, metadata)) continue;
629
+ const firing = goal.firing;
630
+ const cents = firing.value_cents ?? null;
631
+ const currency = firing.currency ?? null;
632
+ fireConversionWithConsent({
633
+ sendTo: firing.send_to,
634
+ value: cents != null && currency ? fromMinor(cents, currency) : null,
635
+ currency,
636
+ // Page-scoped txn id → fire once per (goal, path) per session; engagement conversions
637
+ // shouldn't re-fire as the visitor scrolls back and forth or re-enters a page.
638
+ transactionId: `auto:${goal.key}:${currentPath()}`
639
+ });
640
+ }
641
+ }
642
+ return {
643
+ onAutomaticEvent(eventType, metadata) {
644
+ if (store.isReady()) {
645
+ fireMatching(eventType, metadata);
646
+ return;
647
+ }
648
+ if (pending.length < MAX_BUFFERED_EVENTS) pending.push({ eventType, metadata });
649
+ if (!subscribed) {
650
+ subscribed = true;
651
+ store.onResolve(() => {
652
+ const buffered = pending.splice(0);
653
+ for (const event of buffered) fireMatching(event.eventType, event.metadata);
654
+ });
655
+ }
656
+ }
657
+ };
658
+ }
659
+ function withConversionAutoFire(client, autoFire) {
660
+ return {
661
+ ...client,
662
+ trackEvent: (input) => {
663
+ client.trackEvent(input);
664
+ try {
665
+ autoFire.onAutomaticEvent(input.eventType, input.metadata ?? {});
666
+ } catch {
667
+ }
668
+ }
669
+ };
670
+ }
671
+
316
672
  // ../tracking-core/src/session.ts
317
673
  var VISITOR_STORAGE_KEY = "aranova_tracking_visitor";
318
674
  var SESSION_STORAGE_KEY = "aranova_tracking_session";
@@ -1049,7 +1405,7 @@ function attachScrollDepth(client, config) {
1049
1405
  }
1050
1406
  const thresholds = new Set(config.thresholds);
1051
1407
  let firedForPath = /* @__PURE__ */ new Set();
1052
- let currentPath = window.location.pathname;
1408
+ let currentPath2 = window.location.pathname;
1053
1409
  let rafId = null;
1054
1410
  function getScrollPercent() {
1055
1411
  const doc = document.documentElement;
@@ -1068,7 +1424,7 @@ function attachScrollDepth(client, config) {
1068
1424
  eventType: "scroll_depth",
1069
1425
  metadata: {
1070
1426
  depth_percent: threshold,
1071
- page: { path: currentPath }
1427
+ page: { path: currentPath2 }
1072
1428
  },
1073
1429
  pageUrl: window.location.href,
1074
1430
  occurredAt: null
@@ -1085,8 +1441,8 @@ function attachScrollDepth(client, config) {
1085
1441
  }
1086
1442
  function resetIfPathChanged() {
1087
1443
  const newPath = window.location.pathname;
1088
- if (newPath === currentPath) return;
1089
- currentPath = newPath;
1444
+ if (newPath === currentPath2) return;
1445
+ currentPath2 = newPath;
1090
1446
  firedForPath = /* @__PURE__ */ new Set();
1091
1447
  setTimeout(checkThresholds, 0);
1092
1448
  }
@@ -1122,7 +1478,7 @@ function attachFormStart(client, config) {
1122
1478
  }
1123
1479
  const selector = config.selector ?? "form";
1124
1480
  let firedForms = /* @__PURE__ */ new Set();
1125
- let currentPath = window.location.pathname;
1481
+ let currentPath2 = window.location.pathname;
1126
1482
  function getFormKey(form) {
1127
1483
  if (form.id) return `id:${form.id}`;
1128
1484
  const explicitAction = form.getAttribute("action");
@@ -1153,8 +1509,8 @@ function attachFormStart(client, config) {
1153
1509
  }
1154
1510
  function resetIfPathChanged() {
1155
1511
  const newPath = window.location.pathname;
1156
- if (newPath === currentPath) return;
1157
- currentPath = newPath;
1512
+ if (newPath === currentPath2) return;
1513
+ currentPath2 = newPath;
1158
1514
  firedForms = /* @__PURE__ */ new Set();
1159
1515
  }
1160
1516
  const originalPushState = history.pushState.bind(history);
@@ -1233,21 +1589,64 @@ async function salesRequest(config, method, path, body) {
1233
1589
  }
1234
1590
 
1235
1591
  // ../tracking-core/src/resources/sales/client.ts
1592
+ function fireRecordedConversions(firing, input, recorded, sale, currency) {
1593
+ if (!firing) return;
1594
+ const txnBase = input.external_id ?? sale.id;
1595
+ for (const item of recorded) {
1596
+ if (!item.service) continue;
1597
+ const config = firing.getFiring(item.service);
1598
+ if (!config) continue;
1599
+ const cents = item.amount_cents ?? config.value_cents ?? null;
1600
+ fireConversionWithConsent({
1601
+ sendTo: config.send_to,
1602
+ value: cents != null ? fromMinor(cents, currency) : null,
1603
+ currency: config.currency ?? currency,
1604
+ transactionId: `${txnBase}:${item.service}`
1605
+ });
1606
+ }
1607
+ }
1236
1608
  function createSalesClient(config) {
1237
- return {
1238
- async record(input) {
1239
- const currency = input.currency ?? config.defaultCurrency;
1240
- if (!currency) {
1241
- throw new Error(
1242
- "record: `currency` is required (pass it on the sale or set config.defaultCurrency)"
1243
- );
1609
+ async function record(input) {
1610
+ const currency = input.currency ?? config.defaultCurrency;
1611
+ if (!currency) {
1612
+ throw new Error(
1613
+ "record: `currency` is required (pass it on the sale or set config.defaultCurrency)"
1614
+ );
1615
+ }
1616
+ const body = {
1617
+ ...input,
1618
+ currency,
1619
+ occurred_at: input.occurred_at ?? (/* @__PURE__ */ new Date()).toISOString()
1620
+ };
1621
+ const sale = await salesRequest(config, "POST", "/sales", body);
1622
+ const recorded = input.services?.length ? input.services.map((s) => ({
1623
+ service: s.service,
1624
+ amount_cents: s.amount_cents
1625
+ })) : [
1626
+ {
1627
+ service: input.service,
1628
+ amount_cents: input.amount_total_cents ?? null
1244
1629
  }
1245
- const body = {
1246
- ...input,
1630
+ ];
1631
+ fireRecordedConversions(config.firing, input, recorded, sale, currency);
1632
+ return sale;
1633
+ }
1634
+ return {
1635
+ record,
1636
+ // recordSale is the intent-revealing alias — same behavior, clearer call site.
1637
+ recordSale: record,
1638
+ trackConversion(key, options) {
1639
+ const firing = config.firing?.getFiring(key);
1640
+ if (!firing) return;
1641
+ const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
1642
+ const cents = firing.value_cents ?? null;
1643
+ const value = options?.value ?? (cents != null && currency ? fromMinor(cents, currency) : null);
1644
+ fireConversionWithConsent({
1645
+ sendTo: firing.send_to,
1646
+ value,
1247
1647
  currency,
1248
- occurred_at: input.occurred_at ?? (/* @__PURE__ */ new Date()).toISOString()
1249
- };
1250
- return salesRequest(config, "POST", "/sales", body);
1648
+ transactionId: options?.transactionId ?? null
1649
+ });
1251
1650
  },
1252
1651
  async list(query) {
1253
1652
  const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
@@ -1341,39 +1740,6 @@ function createSalesClient(config) {
1341
1740
  };
1342
1741
  }
1343
1742
 
1344
- // ../tracking-core/src/resources/sales/money.ts
1345
- var MINOR_UNIT_EXPONENT = {
1346
- USD: 2,
1347
- CAD: 2
1348
- };
1349
- function exponentFor(currency) {
1350
- return MINOR_UNIT_EXPONENT[currency] ?? 2;
1351
- }
1352
- function toMinor(amount, currency) {
1353
- return Math.round(amount * 10 ** exponentFor(currency));
1354
- }
1355
- function fromMinor(cents, currency) {
1356
- return cents / 10 ** exponentFor(currency);
1357
- }
1358
- function formatMoney(cents, currency, locale) {
1359
- return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
1360
- fromMinor(cents, currency)
1361
- );
1362
- }
1363
- function formatDateInTz(iso, timeZone, opts, locale) {
1364
- const date = new Date(iso);
1365
- if (Number.isNaN(date.getTime())) return iso;
1366
- return new Intl.DateTimeFormat(locale, {
1367
- year: "numeric",
1368
- month: "short",
1369
- day: "2-digit",
1370
- hour: "2-digit",
1371
- minute: "2-digit",
1372
- ...opts,
1373
- timeZone
1374
- }).format(date);
1375
- }
1376
-
1377
1743
  // ../tracking-core/src/resources/sales/schema.ts
1378
1744
  import { z as z11 } from "zod";
1379
1745
  var SUPPORTED_CURRENCIES = ["USD", "CAD"];
@@ -1838,7 +2204,7 @@ function GoogleAdsTracking(props) {
1838
2204
  import { usePathname, useSearchParams } from "next/navigation";
1839
2205
 
1840
2206
  // package.json
1841
- var version = "0.13.0";
2207
+ var version = "0.14.1";
1842
2208
 
1843
2209
  // src/factory.tsx
1844
2210
  import { createContext as createContext2, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo2, useRef } from "react";
@@ -1939,7 +2305,7 @@ var PhoneField = forwardRef(function PhoneField2({ country, value, defaultValue,
1939
2305
  // src/factory.tsx
1940
2306
  import { jsx as jsx5 } from "react/jsx-runtime";
1941
2307
  function createTracking(options) {
1942
- const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone } = options;
2308
+ const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone, conversionConfig } = options;
1943
2309
  if (!apiKey || !endpoint) {
1944
2310
  if (apiKey || endpoint) {
1945
2311
  console.warn(
@@ -1983,6 +2349,17 @@ function createTracking(options) {
1983
2349
  ),
1984
2350
  []
1985
2351
  );
2352
+ const conversionStore = useMemo2(
2353
+ () => conversionConfig ? resolveConversionConfig({
2354
+ cdnUrl: conversionConfig.cdnUrl,
2355
+ baked: conversionConfig.baked
2356
+ }) : null,
2357
+ []
2358
+ );
2359
+ const wrapClient = useMemo2(() => {
2360
+ const autoFire = conversionStore ? createConversionAutoFire(conversionStore) : null;
2361
+ return (c) => autoFire ? withConversionAutoFire(c, autoFire) : c;
2362
+ }, [conversionStore]);
1986
2363
  useEffect3(() => {
1987
2364
  const rawClient = getOrCreateTrackingClient({
1988
2365
  apiKey,
@@ -1994,7 +2371,7 @@ function createTracking(options) {
1994
2371
  activeGtagIds: gtagIds,
1995
2372
  debug
1996
2373
  });
1997
- fireManualPageView(rawClient);
2374
+ fireManualPageView(wrapClient(rawClient));
1998
2375
  }, [pathname, searchParams]);
1999
2376
  const firedPagesRef = useRef(/* @__PURE__ */ new Set());
2000
2377
  useEffect3(() => {
@@ -2009,14 +2386,18 @@ function createTracking(options) {
2009
2386
  activeGtagIds: gtagIds,
2010
2387
  debug
2011
2388
  });
2389
+ const detectorClient = wrapClient(rawClient);
2012
2390
  for (const { name, pathPattern } of specificPageVisitConfig.pages) {
2013
2391
  if (!pathPattern.test(pathname)) continue;
2014
2392
  const key = `${name}:${pathname}`;
2015
2393
  if (firedPagesRef.current.has(key)) continue;
2016
2394
  firedPagesRef.current.add(key);
2017
- rawClient.trackEvent({
2395
+ detectorClient.trackEvent({
2018
2396
  eventType: "specific_page_visit",
2019
- metadata: { page_name: name, page: { path: pathname } },
2397
+ metadata: {
2398
+ page_name: name,
2399
+ page: { path: pathname }
2400
+ },
2020
2401
  pageUrl: null,
2021
2402
  occurredAt: null
2022
2403
  });
@@ -2033,7 +2414,7 @@ function createTracking(options) {
2033
2414
  activeGtagIds: gtagIds,
2034
2415
  debug
2035
2416
  });
2036
- return attachBfcacheRestore(rawClient);
2417
+ return attachBfcacheRestore(wrapClient(rawClient));
2037
2418
  }, []);
2038
2419
  useEffect3(() => {
2039
2420
  if (!timeOnSiteConfig) return;
@@ -2047,7 +2428,7 @@ function createTracking(options) {
2047
2428
  activeGtagIds: gtagIds,
2048
2429
  debug
2049
2430
  });
2050
- return attachTimeOnSite(rawClient, timeOnSiteConfig);
2431
+ return attachTimeOnSite(wrapClient(rawClient), timeOnSiteConfig);
2051
2432
  }, []);
2052
2433
  const multiPageSessionConfig = triggers.automatic.multi_page_session ?? null;
2053
2434
  const mpsLastPathRef = useRef(null);
@@ -2085,7 +2466,7 @@ function createTracking(options) {
2085
2466
  activeGtagIds: gtagIds,
2086
2467
  debug
2087
2468
  });
2088
- rawClient.trackEvent({
2469
+ wrapClient(rawClient).trackEvent({
2089
2470
  eventType: "multi_page_session",
2090
2471
  metadata: {
2091
2472
  page_count: paths.size,
@@ -2110,13 +2491,14 @@ function createTracking(options) {
2110
2491
  activeGtagIds: gtagIds,
2111
2492
  debug
2112
2493
  });
2494
+ const detectorClient = wrapClient(rawClient);
2113
2495
  const scrollDepth = triggers.automatic.scroll_depth;
2114
2496
  if (scrollDepth) {
2115
- detachers.push(attachScrollDepth(rawClient, scrollDepth));
2497
+ detachers.push(attachScrollDepth(detectorClient, scrollDepth));
2116
2498
  }
2117
2499
  const formStart = triggers.automatic.form_start;
2118
2500
  if (formStart) {
2119
- detachers.push(attachFormStart(rawClient, formStart));
2501
+ detachers.push(attachFormStart(detectorClient, formStart));
2120
2502
  }
2121
2503
  return () => {
2122
2504
  for (let i = detachers.length - 1; i >= 0; i--) {
@@ -2164,6 +2546,7 @@ export {
2164
2546
  parsePhone,
2165
2547
  phoneField,
2166
2548
  resetConsent,
2549
+ resolveConversionConfig,
2167
2550
  saleCreateSchema,
2168
2551
  saleItemSchema,
2169
2552
  saleServiceSchema,