@aranova/tracking-next 0.17.3 → 0.18.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
@@ -220,6 +220,11 @@ function captureTrackingParamsFromLocation(url = typeof window === "undefined" ?
220
220
  }
221
221
 
222
222
  // ../tracking-core/src/gtag.ts
223
+ var GTAG_SCRIPT_HOST = "https://www.googletagmanager.com/gtag/js";
224
+ var TRACKING_SCRIPT_ATTRIBUTE = "data-aranova-tracking";
225
+ function getScriptMarker(id) {
226
+ return `aranova-${id}`;
227
+ }
223
228
  var GTAG_ID_PATTERN = /^[A-Z]{1,3}-[A-Za-z0-9_-]+$/;
224
229
  function isValidGtagId(id) {
225
230
  return GTAG_ID_PATTERN.test(id);
@@ -248,6 +253,15 @@ gtag('js', new Date());
248
253
  gtag('config', '${gtagId}');
249
254
  `.trim();
250
255
  }
256
+ function ensureGtagFunction() {
257
+ window.dataLayer = window.dataLayer || [];
258
+ if (typeof window.gtag === "function") return window.gtag;
259
+ function gtag() {
260
+ window.dataLayer?.push(arguments);
261
+ }
262
+ window.gtag = gtag;
263
+ return window.gtag;
264
+ }
251
265
  var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
252
266
  function isValidSendTo(sendTo) {
253
267
  return SEND_TO_RE.test(sendTo);
@@ -266,6 +280,27 @@ function fireGtagConversion(input) {
266
280
  return false;
267
281
  }
268
282
  }
283
+ function applyDefaultConsentState() {
284
+ const gtag = ensureGtagFunction();
285
+ gtag(
286
+ "consent",
287
+ "default",
288
+ buildConsentPayload(getConsentState() === "denied" ? "denied" : "granted")
289
+ );
290
+ }
291
+ function loadGtagScript(gtagId) {
292
+ if (typeof document === "undefined") return;
293
+ const marker = getScriptMarker("gtag-loader");
294
+ const existingScript = document.querySelector(
295
+ `script[${TRACKING_SCRIPT_ATTRIBUTE}="${marker}"]`
296
+ );
297
+ if (existingScript) return;
298
+ const script = document.createElement("script");
299
+ script.async = true;
300
+ script.src = `${GTAG_SCRIPT_HOST}?id=${encodeURIComponent(gtagId)}`;
301
+ script.setAttribute(TRACKING_SCRIPT_ATTRIBUTE, marker);
302
+ document.head.append(script);
303
+ }
269
304
  function createGtagInitScriptMulti(gtagIds) {
270
305
  const safeIds = gtagIds.filter(isValidGtagId);
271
306
  const configs = safeIds.map((id) => `gtag('config', '${id}');`).join("\n");
@@ -552,6 +587,7 @@ function parseConversionConfig(raw) {
552
587
  business_id: typeof obj.business_id === "string" ? obj.business_id : void 0,
553
588
  customer_id: typeof obj.customer_id === "string" ? obj.customer_id : null,
554
589
  environment: typeof obj.environment === "string" ? obj.environment : void 0,
590
+ google_tracking_state: obj.google_tracking_state === "active" ? "active" : "disabled",
555
591
  gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
556
592
  meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
557
593
  services,
@@ -687,6 +723,283 @@ function formatDateInTz(iso, timeZone, opts, locale) {
687
723
  }).format(date);
688
724
  }
689
725
 
726
+ // ../tracking-core/src/resources/tracking-config-runtime.ts
727
+ var CACHE_PREFIX2 = "_aranova_cfg_runtime_";
728
+ var AUTHORITY_TTL_MS = 6e4;
729
+ var runtimes = /* @__PURE__ */ new Map();
730
+ var configuredIds = /* @__PURE__ */ new Set();
731
+ var scriptLoad = null;
732
+ var jsInitialized = false;
733
+ function cacheKey2(url) {
734
+ return `${CACHE_PREFIX2}${url}`;
735
+ }
736
+ function readCache2(url) {
737
+ if (typeof window === "undefined") return null;
738
+ try {
739
+ const raw = window.sessionStorage.getItem(cacheKey2(url));
740
+ if (!raw) return null;
741
+ const parsed = JSON.parse(raw);
742
+ const config = parseConversionConfig(parsed.config);
743
+ if (!config) return null;
744
+ return {
745
+ etag: typeof parsed.etag === "string" ? parsed.etag : null,
746
+ config
747
+ };
748
+ } catch {
749
+ return null;
750
+ }
751
+ }
752
+ function writeCache2(url, entry) {
753
+ if (typeof window === "undefined") return;
754
+ try {
755
+ window.sessionStorage.setItem(cacheKey2(url), JSON.stringify(entry));
756
+ } catch {
757
+ }
758
+ }
759
+ function isTombstone(config) {
760
+ return config.google_tracking_state === "disabled" || Object.keys(config.gtag_ids).length === 0;
761
+ }
762
+ function validateConfig(config, ref) {
763
+ return config.business_id === ref.businessId && config.environment === ref.environment && (config.google_tracking_state === "active" || config.google_tracking_state === "disabled");
764
+ }
765
+ function pageViewSnapshot() {
766
+ if (typeof window === "undefined" || typeof document === "undefined") return null;
767
+ return {
768
+ href: window.location.href,
769
+ title: document.title || null,
770
+ referrer: document.referrer || null
771
+ };
772
+ }
773
+ function ensureScript(gtagId) {
774
+ if (typeof window === "undefined" || typeof document === "undefined") return Promise.resolve();
775
+ applyDefaultConsentState();
776
+ loadGtagScript(gtagId);
777
+ if (scriptLoad) return scriptLoad;
778
+ scriptLoad = new Promise((resolve) => {
779
+ const script = document.querySelector(
780
+ 'script[data-aranova-tracking="aranova-gtag-loader"]'
781
+ );
782
+ if (!script) {
783
+ resolve();
784
+ return;
785
+ }
786
+ if (script.dataset.loaded === "true") {
787
+ resolve();
788
+ return;
789
+ }
790
+ window.setTimeout(resolve, 0);
791
+ script.addEventListener(
792
+ "load",
793
+ () => {
794
+ script.dataset.loaded = "true";
795
+ resolve();
796
+ },
797
+ { once: true }
798
+ );
799
+ script.addEventListener("error", () => resolve(), { once: true });
800
+ });
801
+ return scriptLoad;
802
+ }
803
+ var TrackingConfigRuntime = class {
804
+ constructor(ref, fetchImpl = globalThis.fetch) {
805
+ this.ref = ref;
806
+ this.fetchImpl = fetchImpl;
807
+ this.current = null;
808
+ this.etag = null;
809
+ this.stateValue = "unconfirmed";
810
+ this.confirmedAt = 0;
811
+ this.inFlight = null;
812
+ this.conversionQueue = [];
813
+ this.automaticQueue = [];
814
+ this.pageQueue = [];
815
+ this.listeners = /* @__PURE__ */ new Set();
816
+ const cached = readCache2(ref.cdnUrl);
817
+ this.current = cached?.config ?? null;
818
+ this.etag = cached?.etag ?? null;
819
+ void this.revalidate();
820
+ if (typeof window !== "undefined") {
821
+ window.addEventListener("visibilitychange", () => {
822
+ if (document.visibilityState === "visible") void this.revalidate();
823
+ });
824
+ window.addEventListener("focus", () => void this.revalidate());
825
+ }
826
+ }
827
+ state() {
828
+ return this.stateValue;
829
+ }
830
+ config() {
831
+ return this.stateValue === "active" || this.stateValue === "tombstone" ? this.current : null;
832
+ }
833
+ __unsafeExpireAuthorityForTests() {
834
+ this.confirmedAt = 0;
835
+ }
836
+ subscribe(listener) {
837
+ this.listeners.add(listener);
838
+ return () => this.listeners.delete(listener);
839
+ }
840
+ async ensureAuthority() {
841
+ if (this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS) {
842
+ return true;
843
+ }
844
+ await this.revalidate();
845
+ return this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS;
846
+ }
847
+ async revalidate() {
848
+ if (typeof window === "undefined" || !this.fetchImpl) return;
849
+ if (this.inFlight) return this.inFlight;
850
+ this.inFlight = this.revalidateNow().finally(() => {
851
+ this.inFlight = null;
852
+ });
853
+ return this.inFlight;
854
+ }
855
+ queuePageView(snapshot = pageViewSnapshot()) {
856
+ if (!snapshot) return;
857
+ this.pageQueue.push(snapshot);
858
+ void this.flush();
859
+ }
860
+ fireConversion(key, options) {
861
+ this.conversionQueue.push({ key, ...options });
862
+ void this.flush();
863
+ }
864
+ queueAutomaticEvent(eventType, metadata, transactionPath) {
865
+ this.automaticQueue.push({ eventType, metadata, transactionPath });
866
+ void this.flush();
867
+ }
868
+ listGoals() {
869
+ return this.current?.goals ?? [];
870
+ }
871
+ async revalidateNow() {
872
+ try {
873
+ const headers = {};
874
+ if (this.etag) headers["If-None-Match"] = this.etag;
875
+ const response = await this.fetchImpl(this.ref.cdnUrl, {
876
+ method: "GET",
877
+ headers,
878
+ cache: "no-cache"
879
+ });
880
+ if (response.status === 304 && this.current && validateConfig(this.current, this.ref)) {
881
+ this.confirm(this.current, this.etag);
882
+ await this.flush();
883
+ return;
884
+ }
885
+ if (!response.ok) {
886
+ this.expireAuthority();
887
+ return;
888
+ }
889
+ const next = parseConversionConfig(await response.json());
890
+ if (!next || !validateConfig(next, this.ref)) {
891
+ this.expireAuthority();
892
+ return;
893
+ }
894
+ if (this.current && next.config_version < this.current.config_version) {
895
+ this.expireAuthority();
896
+ return;
897
+ }
898
+ this.confirm(next, response.headers.get("ETag"));
899
+ await this.flush();
900
+ } catch {
901
+ this.expireAuthority();
902
+ }
903
+ }
904
+ expireAuthority() {
905
+ if (this.stateValue !== "unconfirmed") this.stateValue = "unconfirmed";
906
+ }
907
+ confirm(config, etag) {
908
+ this.current = config;
909
+ this.etag = etag;
910
+ this.confirmedAt = Date.now();
911
+ this.stateValue = isTombstone(config) ? "tombstone" : "active";
912
+ writeCache2(this.ref.cdnUrl, { etag, config });
913
+ if (this.stateValue === "tombstone") {
914
+ this.conversionQueue.length = 0;
915
+ this.automaticQueue.length = 0;
916
+ this.pageQueue.length = 0;
917
+ }
918
+ for (const listener of this.listeners) listener();
919
+ }
920
+ async flush() {
921
+ if (!await this.ensureAuthority()) return;
922
+ if (this.stateValue !== "active" || !this.current) return;
923
+ const ids = Object.values(this.current.gtag_ids).filter(
924
+ (id) => typeof id === "string" && isValidGtagId(id)
925
+ );
926
+ if (ids.length === 0) return;
927
+ await ensureScript(ids[0]);
928
+ const gtag = window.gtag;
929
+ if (typeof gtag !== "function") return;
930
+ if (!jsInitialized) {
931
+ gtag("js", /* @__PURE__ */ new Date());
932
+ jsInitialized = true;
933
+ }
934
+ for (const id of ids) {
935
+ if (configuredIds.has(id)) continue;
936
+ gtag("config", id, { send_page_view: false });
937
+ configuredIds.add(id);
938
+ }
939
+ while (this.pageQueue.length) {
940
+ const page = this.pageQueue.shift();
941
+ gtag("event", "page_view", {
942
+ page_location: page.href,
943
+ page_title: page.title ?? void 0,
944
+ page_referrer: page.referrer ?? void 0
945
+ });
946
+ }
947
+ while (this.automaticQueue.length) {
948
+ const event = this.automaticQueue.shift();
949
+ for (const goal of this.current.goals) {
950
+ if (goal.kind !== "event" || !goal.firing) continue;
951
+ if (!automaticThresholdMet(goal, event.eventType, event.metadata)) continue;
952
+ this.conversionQueue.push({
953
+ key: goal.key,
954
+ transactionId: `auto:${goal.key}:${event.transactionPath}`
955
+ });
956
+ }
957
+ }
958
+ while (this.conversionQueue.length) {
959
+ const item = this.conversionQueue.shift();
960
+ const goal = this.current.goals.find((g) => g.key === item.key);
961
+ const firing = goal?.firing;
962
+ if (!firing || getConsentState() === "denied") continue;
963
+ const currency = item.currency ?? firing.currency ?? null;
964
+ const value = item.value ?? (firing.value_cents != null && currency ? fromMinor(firing.value_cents, currency) : null);
965
+ fireGtagConversion({
966
+ sendTo: firing.send_to,
967
+ value,
968
+ currency,
969
+ transactionId: item.transactionId ?? null
970
+ });
971
+ }
972
+ }
973
+ };
974
+ function automaticThresholdMet(goal, eventType, metadata) {
975
+ const t = goal.trigger;
976
+ if (!t || t.event_type !== eventType) return false;
977
+ switch (eventType) {
978
+ case "scroll_depth":
979
+ return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
980
+ case "time_on_site":
981
+ return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
982
+ case "multi_page_session":
983
+ return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
984
+ case "specific_page_visit":
985
+ return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
986
+ case "page_view":
987
+ case "form_start":
988
+ case "phone_click":
989
+ return true;
990
+ default:
991
+ return false;
992
+ }
993
+ }
994
+ function getTrackingConfigRuntime(ref, fetchImpl) {
995
+ const key = `${ref.cdnUrl}|${ref.businessId}|${ref.environment}`;
996
+ const existing = runtimes.get(key);
997
+ if (existing) return existing;
998
+ const runtime = new TrackingConfigRuntime(ref, fetchImpl ?? globalThis.fetch);
999
+ runtimes.set(key, runtime);
1000
+ return runtime;
1001
+ }
1002
+
690
1003
  // ../tracking-core/src/resources/conversion-autofire.ts
691
1004
  function thresholdMet(goal, eventType, metadata) {
692
1005
  const t = goal.trigger;
@@ -719,6 +1032,12 @@ function createConversionAutoFire(store) {
719
1032
  for (const goal of store.listGoals()) {
720
1033
  if (goal.kind !== "event" || !goal.firing) continue;
721
1034
  if (!thresholdMet(goal, eventType, metadata)) continue;
1035
+ if ("queueAutomaticEvent" in store) {
1036
+ store.fireConversion(goal.key, {
1037
+ transactionId: `auto:${goal.key}:${currentPath()}`
1038
+ });
1039
+ continue;
1040
+ }
722
1041
  const firing = goal.firing;
723
1042
  const cents = firing.value_cents ?? null;
724
1043
  const currency = firing.currency ?? null;
@@ -734,6 +1053,10 @@ function createConversionAutoFire(store) {
734
1053
  }
735
1054
  return {
736
1055
  onAutomaticEvent(eventType, metadata) {
1056
+ if ("queueAutomaticEvent" in store) {
1057
+ store.queueAutomaticEvent(eventType, metadata, currentPath());
1058
+ return;
1059
+ }
737
1060
  if (store.isReady()) {
738
1061
  fireMatching(eventType, metadata);
739
1062
  return;
@@ -1413,69 +1736,154 @@ var timeOnSiteConfigSchema = z11.object({
1413
1736
  thresholdSeconds: z11.number().int().positive()
1414
1737
  }).strict();
1415
1738
 
1739
+ // ../tracking-core/src/events/semantics.ts
1740
+ var EVENT_SEMANTICS = {
1741
+ page_view: {
1742
+ label: "Page view",
1743
+ category: "page",
1744
+ outcomeRole: "navigation",
1745
+ clientVisibility: "simple"
1746
+ },
1747
+ time_on_site: {
1748
+ label: "Time on site",
1749
+ category: "engagement",
1750
+ outcomeRole: "engagement",
1751
+ clientVisibility: "detailed"
1752
+ },
1753
+ specific_page_visit: {
1754
+ label: "Key page visit",
1755
+ category: "engagement",
1756
+ outcomeRole: "engagement",
1757
+ clientVisibility: "detailed"
1758
+ },
1759
+ scroll_depth: {
1760
+ label: "Scroll depth",
1761
+ category: "engagement",
1762
+ outcomeRole: "engagement",
1763
+ clientVisibility: "detailed"
1764
+ },
1765
+ multi_page_session: {
1766
+ label: "Multi-page session",
1767
+ category: "engagement",
1768
+ outcomeRole: "engagement",
1769
+ clientVisibility: "detailed"
1770
+ },
1771
+ form_start: {
1772
+ label: "Form started",
1773
+ category: "engagement",
1774
+ outcomeRole: "engagement",
1775
+ clientVisibility: "simple"
1776
+ },
1777
+ sdk_heartbeat: {
1778
+ label: "SDK heartbeat",
1779
+ category: "system",
1780
+ outcomeRole: "diagnostic",
1781
+ clientVisibility: "hidden"
1782
+ },
1783
+ page_exit: {
1784
+ label: "Page exit",
1785
+ category: "engagement",
1786
+ outcomeRole: "diagnostic",
1787
+ clientVisibility: "detailed"
1788
+ },
1789
+ form_submit: {
1790
+ label: "Form submitted",
1791
+ category: "lead",
1792
+ outcomeRole: "lead",
1793
+ clientVisibility: "simple"
1794
+ },
1795
+ phone_click: {
1796
+ label: "Phone click",
1797
+ category: "lead",
1798
+ outcomeRole: "lead",
1799
+ clientVisibility: "simple"
1800
+ },
1801
+ cta_click: {
1802
+ label: "CTA click",
1803
+ category: "engagement",
1804
+ outcomeRole: "engagement",
1805
+ clientVisibility: "simple"
1806
+ }
1807
+ };
1808
+ function getEventSemantics(eventName) {
1809
+ return eventName in EVENT_SEMANTICS ? EVENT_SEMANTICS[eventName] : null;
1810
+ }
1811
+
1416
1812
  // ../tracking-core/src/events/registry.ts
1417
1813
  var EVENT_REGISTRY = {
1418
1814
  // --- automatic triggers ---
1419
1815
  page_view: {
1420
1816
  kind: "automatic",
1817
+ semantics: EVENT_SEMANTICS.page_view,
1421
1818
  metadataSchema: pageViewMetadataSchema,
1422
1819
  configSchema: pageViewConfigSchema
1423
1820
  },
1424
1821
  time_on_site: {
1425
1822
  kind: "automatic",
1823
+ semantics: EVENT_SEMANTICS.time_on_site,
1426
1824
  metadataSchema: timeOnSiteMetadataSchema,
1427
1825
  configSchema: timeOnSiteConfigSchema
1428
1826
  },
1429
1827
  specific_page_visit: {
1430
1828
  kind: "automatic",
1829
+ semantics: EVENT_SEMANTICS.specific_page_visit,
1431
1830
  metadataSchema: specificPageVisitMetadataSchema,
1432
1831
  configSchema: specificPageVisitConfigSchema
1433
1832
  },
1434
1833
  scroll_depth: {
1435
1834
  kind: "automatic",
1835
+ semantics: EVENT_SEMANTICS.scroll_depth,
1436
1836
  metadataSchema: scrollDepthMetadataSchema,
1437
1837
  configSchema: scrollDepthConfigSchema
1438
1838
  },
1439
1839
  multi_page_session: {
1440
1840
  kind: "automatic",
1841
+ semantics: EVENT_SEMANTICS.multi_page_session,
1441
1842
  metadataSchema: multiPageSessionMetadataSchema,
1442
1843
  configSchema: multiPageSessionConfigSchema
1443
1844
  },
1444
1845
  form_start: {
1445
1846
  kind: "automatic",
1847
+ semantics: EVENT_SEMANTICS.form_start,
1446
1848
  metadataSchema: formStartMetadataSchema,
1447
1849
  configSchema: formStartConfigSchema
1448
1850
  },
1449
1851
  // --- SDK-internal automatic (not consumer-configurable) ---
1450
1852
  sdk_heartbeat: {
1451
1853
  kind: "automatic",
1854
+ semantics: EVENT_SEMANTICS.sdk_heartbeat,
1452
1855
  metadataSchema: sdkHeartbeatMetadataSchema,
1453
1856
  configSchema: sdkHeartbeatConfigSchema
1454
1857
  },
1455
1858
  page_exit: {
1456
1859
  kind: "automatic",
1860
+ semantics: EVENT_SEMANTICS.page_exit,
1457
1861
  metadataSchema: pageExitMetadataSchema,
1458
1862
  configSchema: pageExitConfigSchema
1459
1863
  },
1460
1864
  // --- manual triggers ---
1461
1865
  form_submit: {
1462
1866
  kind: "manual",
1867
+ semantics: EVENT_SEMANTICS.form_submit,
1463
1868
  metadataSchema: formSubmitMetadataSchema,
1464
1869
  configSchema: formSubmitConfigSchema
1465
1870
  },
1466
1871
  phone_click: {
1467
1872
  kind: "manual",
1873
+ semantics: EVENT_SEMANTICS.phone_click,
1468
1874
  metadataSchema: phoneClickMetadataSchema,
1469
1875
  configSchema: phoneClickConfigSchema
1470
1876
  },
1471
1877
  cta_click: {
1472
1878
  kind: "manual",
1879
+ semantics: EVENT_SEMANTICS.cta_click,
1473
1880
  metadataSchema: ctaClickMetadataSchema,
1474
1881
  configSchema: ctaClickConfigSchema
1475
1882
  }
1476
1883
  };
1477
1884
  var ALL_AUTOMATIC_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "automatic").map(([name]) => name);
1478
1885
  var ALL_MANUAL_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "manual").map(([name]) => name);
1886
+ var ALL_LEAD_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.semantics.outcomeRole === "lead").map(([name]) => name);
1479
1887
  function getEventDefinition(name) {
1480
1888
  return EVENT_REGISTRY[name];
1481
1889
  }
@@ -2073,6 +2481,14 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
2073
2481
  const txnBase = input.external_id ?? sale.id;
2074
2482
  for (const item of recorded) {
2075
2483
  if (!item.service) continue;
2484
+ if ("fireConversion" in firing) {
2485
+ firing.fireConversion(item.service, {
2486
+ value: item.amount_cents != null ? fromMinor(item.amount_cents, currency) : void 0,
2487
+ currency,
2488
+ transactionId: `${txnBase}:${item.service}`
2489
+ });
2490
+ continue;
2491
+ }
2076
2492
  const config = firing.getFiring(item.service);
2077
2493
  if (!config) continue;
2078
2494
  const cents = item.amount_cents ?? config.value_cents ?? null;
@@ -2115,6 +2531,14 @@ function createSalesClient(config) {
2115
2531
  // recordSale is the intent-revealing alias — same behavior, clearer call site.
2116
2532
  recordSale: record,
2117
2533
  trackConversion(key, options) {
2534
+ if (config.firing && "fireConversion" in config.firing) {
2535
+ config.firing.fireConversion(key, {
2536
+ value: options?.value ?? void 0,
2537
+ currency: options?.currency ?? config.defaultCurrency ?? void 0,
2538
+ transactionId: options?.transactionId ?? null
2539
+ });
2540
+ return;
2541
+ }
2118
2542
  const firing = config.firing?.getFiring(key);
2119
2543
  if (!firing) return;
2120
2544
  const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
@@ -2620,14 +3044,24 @@ var ANIMATION_KEYFRAMES = `
2620
3044
 
2621
3045
  // src/AdPlatformTracking.tsx
2622
3046
  import Script from "next/script";
3047
+ import { useEffect as useEffect3 } from "react";
2623
3048
  import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2624
3049
  function AdPlatformTracking({
2625
3050
  gtagId,
2626
3051
  gtagIds,
3052
+ trackingConfig,
3053
+ standalonePageView = false,
2627
3054
  metaPixelId,
2628
3055
  metaPixelIds
2629
3056
  }) {
2630
- const gtagAll = gtagIds ? Object.values(gtagIds).filter((id) => id != null) : gtagId ? [gtagId] : [];
3057
+ const trackingConfigKey = trackingConfig ? `${trackingConfig.cdnUrl}:${trackingConfig.businessId}:${trackingConfig.environment}` : "";
3058
+ useEffect3(() => {
3059
+ if (!trackingConfig) return;
3060
+ const runtime = getTrackingConfigRuntime(trackingConfig);
3061
+ if (standalonePageView) runtime.queuePageView();
3062
+ else void runtime.revalidate();
3063
+ }, [trackingConfigKey, standalonePageView]);
3064
+ const gtagAll = trackingConfig ? [] : gtagIds ? Object.values(gtagIds).filter((id) => id != null) : gtagId ? [gtagId] : [];
2631
3065
  const metaAll = metaPixelIds ? Object.values(metaPixelIds).filter((id) => id != null) : metaPixelId ? [metaPixelId] : [];
2632
3066
  const gtagLoaderId = gtagAll[0];
2633
3067
  const gtagInitScript = gtagAll.length === 1 ? createGtagInitScript(gtagAll[0]) : createGtagInitScriptMulti(gtagAll);
@@ -2677,7 +3111,7 @@ function GoogleAdsTracking(props) {
2677
3111
  import { usePathname, useSearchParams } from "next/navigation";
2678
3112
 
2679
3113
  // package.json
2680
- var version = "0.17.3";
3114
+ var version = "0.18.1";
2681
3115
 
2682
3116
  // src/factory.tsx
2683
3117
  import {
@@ -2685,7 +3119,7 @@ import {
2685
3119
  Suspense,
2686
3120
  useCallback as useCallback3,
2687
3121
  useContext as useContext2,
2688
- useEffect as useEffect3,
3122
+ useEffect as useEffect4,
2689
3123
  useMemo as useMemo2,
2690
3124
  useRef
2691
3125
  } from "react";
@@ -2788,13 +3222,23 @@ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2788
3222
  function PageViewTracker({ fire }) {
2789
3223
  const pathname = usePathname();
2790
3224
  const searchParams = useSearchParams();
2791
- useEffect3(() => {
3225
+ useEffect4(() => {
2792
3226
  fire();
2793
3227
  }, [pathname, searchParams, fire]);
2794
3228
  return null;
2795
3229
  }
2796
3230
  function createTracking(options) {
2797
- const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone, conversionConfig } = options;
3231
+ const {
3232
+ apiKey,
3233
+ endpoint,
3234
+ triggers,
3235
+ environment,
3236
+ gtagIds,
3237
+ debug,
3238
+ phone,
3239
+ conversionConfig,
3240
+ trackingConfig
3241
+ } = options;
2798
3242
  if (!apiKey || !endpoint) {
2799
3243
  if (apiKey || endpoint) {
2800
3244
  console.warn(
@@ -2838,7 +3282,7 @@ function createTracking(options) {
2838
3282
  []
2839
3283
  );
2840
3284
  const conversionStore = useMemo2(
2841
- () => conversionConfig ? resolveConversionConfig({
3285
+ () => trackingConfig ? getTrackingConfigRuntime(trackingConfig) : conversionConfig ? resolveConversionConfig({
2842
3286
  cdnUrl: conversionConfig.cdnUrl,
2843
3287
  baked: conversionConfig.baked
2844
3288
  }) : null,
@@ -2860,9 +3304,10 @@ function createTracking(options) {
2860
3304
  debug
2861
3305
  });
2862
3306
  fireManualPageView(wrapClient(rawClient));
3307
+ if (trackingConfig) getTrackingConfigRuntime(trackingConfig).queuePageView();
2863
3308
  }, [wrapClient]);
2864
3309
  const firedPagesRef = useRef(/* @__PURE__ */ new Set());
2865
- useEffect3(() => {
3310
+ useEffect4(() => {
2866
3311
  if (!specificPageVisitConfig || pathname === null) return;
2867
3312
  const rawClient = getOrCreateTrackingClient({
2868
3313
  apiKey,
@@ -2893,7 +3338,7 @@ function createTracking(options) {
2893
3338
  }, [pathname]);
2894
3339
  const multiPageSessionConfig = triggers.automatic.multi_page_session ?? null;
2895
3340
  const mpsLastPathRef = useRef(null);
2896
- useEffect3(() => {
3341
+ useEffect4(() => {
2897
3342
  if (!multiPageSessionConfig || pathname === null) return;
2898
3343
  if (pathname === mpsLastPathRef.current) return;
2899
3344
  mpsLastPathRef.current = pathname;
@@ -2940,7 +3385,7 @@ function createTracking(options) {
2940
3385
  } catch {
2941
3386
  }
2942
3387
  }, [pathname]);
2943
- useEffect3(() => {
3388
+ useEffect4(() => {
2944
3389
  const rawClient = getOrCreateTrackingClient({
2945
3390
  apiKey,
2946
3391
  endpoint,
@@ -3004,6 +3449,7 @@ export {
3004
3449
  ConsentBanner,
3005
3450
  DEFAULT_DECLINE_TTL_DAYS,
3006
3451
  DEFAULT_PHONE_COUNTRY,
3452
+ EVENT_SEMANTICS,
3007
3453
  GoogleAdsTracking,
3008
3454
  NAMED_RANGES,
3009
3455
  PhoneField,
@@ -3024,6 +3470,8 @@ export {
3024
3470
  fromMinor,
3025
3471
  getConsentChoice,
3026
3472
  getConsentState,
3473
+ getEventSemantics,
3474
+ getTrackingConfigRuntime,
3027
3475
  onConsentChange,
3028
3476
  optIn,
3029
3477
  optOut,