@aranova/tracking-react 0.4.2 → 0.5.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
@@ -229,7 +229,7 @@ function getVisitorId() {
229
229
  }
230
230
  function getOrRotateSessionId(now = Date.now()) {
231
231
  if (typeof window === "undefined")
232
- return safeUuid();
232
+ return { id: safeUuid(), isNew: true };
233
233
  const raw = readLocalStorage(SESSION_STORAGE_KEY);
234
234
  if (raw) {
235
235
  try {
@@ -238,7 +238,7 @@ function getOrRotateSessionId(now = Date.now()) {
238
238
  if (now - parsed.last_event_at <= SESSION_IDLE_MS) {
239
239
  const refreshed = { id: parsed.id, last_event_at: now };
240
240
  writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(refreshed));
241
- return parsed.id;
241
+ return { id: parsed.id, isNew: false };
242
242
  }
243
243
  }
244
244
  } catch {
@@ -246,7 +246,7 @@ function getOrRotateSessionId(now = Date.now()) {
246
246
  }
247
247
  const fresh = { id: safeUuid(), last_event_at: now };
248
248
  writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
249
- return fresh.id;
249
+ return { id: fresh.id, isNew: true };
250
250
  }
251
251
 
252
252
  // ../tracking-core/src/events/page-view.ts
@@ -386,6 +386,56 @@ function attachAutoPageView(client, options = {}) {
386
386
  };
387
387
  }
388
388
 
389
+ // ../tracking-core/src/heartbeat.ts
390
+ function serializeValue(value) {
391
+ if (value instanceof RegExp) return value.source;
392
+ if (Array.isArray(value)) return value.map(serializeValue);
393
+ if (value !== null && typeof value === "object") {
394
+ const out = {};
395
+ for (const [k, v] of Object.entries(value)) {
396
+ out[k] = serializeValue(v);
397
+ }
398
+ return out;
399
+ }
400
+ return value;
401
+ }
402
+ function buildHeartbeatMetadata(surface, sdkVersion, packageName, triggers) {
403
+ const automaticNames = triggers ? Object.keys(triggers.automatic) : [];
404
+ const manualNames = triggers?.manual ? Object.keys(triggers.manual) : [];
405
+ let triggerConfig = null;
406
+ if (triggers) {
407
+ const cfg = {};
408
+ for (const [name, config] of Object.entries(triggers.automatic)) {
409
+ const serialized = serializeValue(config);
410
+ if (Object.keys(serialized).length > 0) {
411
+ cfg[name] = serialized;
412
+ }
413
+ }
414
+ if (triggers.manual) {
415
+ for (const [name, config] of Object.entries(triggers.manual)) {
416
+ if (config === void 0) continue;
417
+ const serialized = serializeValue(config);
418
+ if (Object.keys(serialized).length > 0) {
419
+ cfg[name] = serialized;
420
+ }
421
+ }
422
+ }
423
+ if (Object.keys(cfg).length > 0) {
424
+ triggerConfig = cfg;
425
+ }
426
+ }
427
+ return {
428
+ sdk_version: sdkVersion ?? "unknown",
429
+ package_name: packageName,
430
+ surface,
431
+ triggers: {
432
+ automatic: automaticNames,
433
+ manual: manualNames
434
+ },
435
+ trigger_config: triggerConfig
436
+ };
437
+ }
438
+
389
439
  // ../tracking-core/src/ingest.ts
390
440
  var DEFAULT_FLUSH_INTERVAL_MS = 2e3;
391
441
  var DEFAULT_MAX_QUEUE_SIZE = 10;
@@ -465,11 +515,33 @@ function createTrackingClient(config) {
465
515
  let firstPage = null;
466
516
  let destroyed = false;
467
517
  const visitorId = getVisitorId();
468
- let sessionId = getOrRotateSessionId();
518
+ const initialSession = getOrRotateSessionId();
519
+ let sessionId = initialSession.id;
469
520
  if (typeof window !== "undefined")
470
521
  firstPage = window.location.href;
522
+ function enqueueHeartbeat() {
523
+ const metadata = buildHeartbeatMetadata(
524
+ config.surface,
525
+ sdkVersion,
526
+ packageName,
527
+ config.triggers ?? null
528
+ );
529
+ queue.push({
530
+ event_type: "sdk_heartbeat",
531
+ page_url: typeof window === "undefined" ? null : window.location.href,
532
+ metadata,
533
+ occurred_at: (/* @__PURE__ */ new Date()).toISOString()
534
+ });
535
+ }
536
+ if (initialSession.isNew) {
537
+ enqueueHeartbeat();
538
+ }
471
539
  function buildSessionPayload() {
472
- sessionId = getOrRotateSessionId();
540
+ const rotated = getOrRotateSessionId();
541
+ if (rotated.isNew && rotated.id !== sessionId) {
542
+ enqueueHeartbeat();
543
+ }
544
+ sessionId = rotated.id;
473
545
  const params = readTrackingParams();
474
546
  const context = buildContext(config.surface, sdkVersion, packageName);
475
547
  return {
@@ -570,60 +642,144 @@ function createTrackingClient(config) {
570
642
  };
571
643
  }
572
644
 
573
- // ../tracking-core/src/events/contact-page-visit.ts
645
+ // ../tracking-core/src/events/cta-click.ts
574
646
  import { z as z2 } from "zod";
575
- var contactPageVisitMetadataSchema = z2.object({
647
+ var ctaClickMetadataSchema = z2.object({
648
+ cta_name: z2.string(),
576
649
  page: z2.object({
577
650
  path: z2.string()
578
- })
579
- }).strict();
580
- var contactPageVisitConfigSchema = z2.object({
581
- // RegExp is runtime-only so we wrap it via z.custom. Consumers pass a
582
- // real regex at createTracking() time; the factory validates with this
583
- // schema and then keeps the live RegExp reference for runtime matching.
584
- pathPattern: z2.custom(
585
- (value) => value instanceof RegExp,
586
- { message: "pathPattern must be a RegExp" }
587
- )
651
+ }),
652
+ section: z2.string().nullable().optional(),
653
+ destination_url: z2.string().nullable().optional()
588
654
  }).strict();
655
+ var ctaClickConfigSchema = z2.object({}).strict();
589
656
 
590
- // ../tracking-core/src/events/form-submit.ts
657
+ // ../tracking-core/src/events/sdk-heartbeat.ts
591
658
  import { z as z3 } from "zod";
592
- var formSubmitMetadataSchema = z3.object({
593
- form: z3.object({
594
- id: z3.string(),
595
- action: z3.string().nullable()
596
- }),
597
- page: z3.object({
598
- path: z3.string()
599
- })
659
+ var sdkHeartbeatTriggersSchema = z3.object({
660
+ automatic: z3.array(z3.string()),
661
+ manual: z3.array(z3.string())
662
+ }).strict();
663
+ var sdkHeartbeatMetadataSchema = z3.object({
664
+ sdk_version: z3.string(),
665
+ package_name: z3.string().nullable(),
666
+ surface: z3.enum(["next", "react", "script"]),
667
+ triggers: sdkHeartbeatTriggersSchema,
668
+ trigger_config: z3.record(z3.string(), z3.record(z3.string(), z3.unknown())).nullable().optional()
600
669
  }).strict();
601
- var formSubmitConfigSchema = z3.object({}).strict();
670
+ var sdkHeartbeatConfigSchema = z3.object({}).strict();
602
671
 
603
- // ../tracking-core/src/events/phone-click.ts
672
+ // ../tracking-core/src/events/form-start.ts
604
673
  import { z as z4 } from "zod";
605
- var phoneClickMetadataSchema = z4.object({
606
- element: z4.object({
607
- tag: z4.string(),
608
- text: z4.string().nullable(),
609
- href: z4.string()
674
+ var formStartMetadataSchema = z4.object({
675
+ form: z4.object({
676
+ id: z4.string(),
677
+ action: z4.string().nullable()
610
678
  }),
611
679
  page: z4.object({
612
680
  path: z4.string()
613
681
  })
614
682
  }).strict();
615
- var phoneClickConfigSchema = z4.object({}).strict();
683
+ var formStartConfigSchema = z4.object({
684
+ selector: z4.string().optional()
685
+ }).strict();
616
686
 
617
- // ../tracking-core/src/events/time-on-site.ts
687
+ // ../tracking-core/src/events/form-submit.ts
618
688
  import { z as z5 } from "zod";
619
- var timeOnSiteMetadataSchema = z5.object({
620
- duration_ms: z5.number().int().nonnegative(),
689
+ var formSubmitMetadataSchema = z5.object({
690
+ form: z5.object({
691
+ id: z5.string(),
692
+ action: z5.string().nullable(),
693
+ fields: z5.array(
694
+ z5.object({
695
+ name: z5.string(),
696
+ type: z5.string(),
697
+ label: z5.string().nullable(),
698
+ has_value: z5.boolean()
699
+ })
700
+ ).optional()
701
+ }),
621
702
  page: z5.object({
622
703
  path: z5.string()
623
704
  })
624
705
  }).strict();
625
- var timeOnSiteConfigSchema = z5.object({
626
- thresholdSeconds: z5.number().int().positive()
706
+ var formSubmitConfigSchema = z5.object({}).strict();
707
+
708
+ // ../tracking-core/src/events/multi-page-session.ts
709
+ import { z as z6 } from "zod";
710
+ var multiPageSessionMetadataSchema = z6.object({
711
+ page_count: z6.number().int().min(2),
712
+ page: z6.object({
713
+ path: z6.string()
714
+ })
715
+ }).strict();
716
+ var multiPageSessionConfigSchema = z6.object({
717
+ pageThreshold: z6.number().int().min(2)
718
+ }).strict();
719
+
720
+ // ../tracking-core/src/events/phone-click.ts
721
+ import { z as z7 } from "zod";
722
+ var phoneClickMetadataSchema = z7.object({
723
+ phone_number: z7.string(),
724
+ page: z7.object({
725
+ path: z7.string()
726
+ }),
727
+ section: z7.string().nullable().optional()
728
+ }).strict();
729
+ var phoneClickConfigSchema = z7.object({}).strict();
730
+
731
+ // ../tracking-core/src/events/scroll-depth.ts
732
+ import { z as z8 } from "zod";
733
+ var scrollDepthMetadataSchema = z8.object({
734
+ depth_percent: z8.number().int().min(1).max(100),
735
+ page: z8.object({
736
+ path: z8.string()
737
+ })
738
+ }).strict();
739
+ var scrollDepthConfigSchema = z8.object({
740
+ thresholds: z8.array(z8.number().int().min(1).max(100)).min(1)
741
+ }).strict();
742
+
743
+ // ../tracking-core/src/events/specific-page-visit.ts
744
+ import { z as z9 } from "zod";
745
+ var SPECIFIC_PAGE_NAMES = [
746
+ "contact_page",
747
+ "about_page",
748
+ "services_page",
749
+ "booking_page",
750
+ "location_page",
751
+ "pricing_page",
752
+ "faq_page",
753
+ "testimonials_page"
754
+ ];
755
+ var specificPageNameSchema = z9.enum(SPECIFIC_PAGE_NAMES);
756
+ var specificPageVisitMetadataSchema = z9.object({
757
+ page_name: specificPageNameSchema,
758
+ page: z9.object({
759
+ path: z9.string()
760
+ })
761
+ }).strict();
762
+ var specificPageVisitConfigSchema = z9.object({
763
+ pages: z9.array(
764
+ z9.object({
765
+ name: specificPageNameSchema,
766
+ pathPattern: z9.custom((value) => value instanceof RegExp, {
767
+ message: "pathPattern must be a RegExp"
768
+ })
769
+ })
770
+ ).min(1)
771
+ }).strict();
772
+
773
+ // ../tracking-core/src/events/time-on-site.ts
774
+ import { z as z10 } from "zod";
775
+ var timeOnSiteMetadataSchema = z10.object({
776
+ duration_ms: z10.number().int().nonnegative(),
777
+ page: z10.object({
778
+ path: z10.string()
779
+ })
780
+ }).strict();
781
+ var timeOnSiteConfigSchema = z10.object({
782
+ thresholdSeconds: z10.number().int().positive()
627
783
  }).strict();
628
784
 
629
785
  // ../tracking-core/src/events/registry.ts
@@ -639,10 +795,31 @@ var EVENT_REGISTRY = {
639
795
  metadataSchema: timeOnSiteMetadataSchema,
640
796
  configSchema: timeOnSiteConfigSchema
641
797
  },
642
- contact_page_visit: {
798
+ specific_page_visit: {
799
+ kind: "automatic",
800
+ metadataSchema: specificPageVisitMetadataSchema,
801
+ configSchema: specificPageVisitConfigSchema
802
+ },
803
+ scroll_depth: {
643
804
  kind: "automatic",
644
- metadataSchema: contactPageVisitMetadataSchema,
645
- configSchema: contactPageVisitConfigSchema
805
+ metadataSchema: scrollDepthMetadataSchema,
806
+ configSchema: scrollDepthConfigSchema
807
+ },
808
+ multi_page_session: {
809
+ kind: "automatic",
810
+ metadataSchema: multiPageSessionMetadataSchema,
811
+ configSchema: multiPageSessionConfigSchema
812
+ },
813
+ form_start: {
814
+ kind: "automatic",
815
+ metadataSchema: formStartMetadataSchema,
816
+ configSchema: formStartConfigSchema
817
+ },
818
+ // --- SDK-internal automatic (not consumer-configurable) ---
819
+ sdk_heartbeat: {
820
+ kind: "automatic",
821
+ metadataSchema: sdkHeartbeatMetadataSchema,
822
+ configSchema: sdkHeartbeatConfigSchema
646
823
  },
647
824
  // --- manual triggers ---
648
825
  form_submit: {
@@ -654,6 +831,11 @@ var EVENT_REGISTRY = {
654
831
  kind: "manual",
655
832
  metadataSchema: phoneClickMetadataSchema,
656
833
  configSchema: phoneClickConfigSchema
834
+ },
835
+ cta_click: {
836
+ kind: "manual",
837
+ metadataSchema: ctaClickMetadataSchema,
838
+ configSchema: ctaClickConfigSchema
657
839
  }
658
840
  };
659
841
  var ALL_AUTOMATIC_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "automatic").map(([name]) => name);
@@ -744,26 +926,193 @@ function attachTimeOnSite(client, config) {
744
926
  };
745
927
  }
746
928
 
747
- // ../tracking-core/src/triggers/contact-page-visit.ts
748
- function attachContactPageVisit(client, config) {
929
+ // ../tracking-core/src/triggers/specific-page-visit.ts
930
+ function attachSpecificPageVisit(client, config) {
749
931
  if (typeof window === "undefined" || typeof history === "undefined") {
750
932
  return () => {
751
933
  };
752
934
  }
753
- const { pathPattern } = config;
754
- let lastFiredPath = null;
935
+ const { pages } = config;
936
+ const firedSet = /* @__PURE__ */ new Set();
755
937
  function check() {
756
938
  const path = window.location.pathname;
757
- if (!pathPattern.test(path)) return;
758
- if (lastFiredPath === path) return;
759
- lastFiredPath = path;
760
- client.trackEvent({
761
- eventType: "contact_page_visit",
762
- metadata: { page: { path } },
763
- pageUrl: window.location.href,
764
- occurredAt: null
939
+ for (const { name, pathPattern } of pages) {
940
+ pathPattern.lastIndex = 0;
941
+ if (!pathPattern.test(path)) continue;
942
+ const key = `${name}:${path}`;
943
+ if (firedSet.has(key)) continue;
944
+ firedSet.add(key);
945
+ client.trackEvent({
946
+ eventType: "specific_page_visit",
947
+ metadata: { page_name: name, page: { path } },
948
+ pageUrl: window.location.href,
949
+ occurredAt: null
950
+ });
951
+ }
952
+ }
953
+ const originalPushState = history.pushState.bind(history);
954
+ const originalReplaceState = history.replaceState.bind(history);
955
+ function patchedPushState(...args) {
956
+ originalPushState(...args);
957
+ setTimeout(check, 0);
958
+ }
959
+ function patchedReplaceState(...args) {
960
+ originalReplaceState(...args);
961
+ setTimeout(check, 0);
962
+ }
963
+ history.pushState = patchedPushState;
964
+ history.replaceState = patchedReplaceState;
965
+ window.addEventListener("popstate", check);
966
+ check();
967
+ return () => {
968
+ history.pushState = originalPushState;
969
+ history.replaceState = originalReplaceState;
970
+ window.removeEventListener("popstate", check);
971
+ };
972
+ }
973
+
974
+ // ../tracking-core/src/triggers/scroll-depth.ts
975
+ function attachScrollDepth(client, config) {
976
+ if (typeof window === "undefined" || typeof document === "undefined") {
977
+ return () => {
978
+ };
979
+ }
980
+ const thresholds = new Set(config.thresholds);
981
+ let firedForPath = /* @__PURE__ */ new Set();
982
+ let currentPath = window.location.pathname;
983
+ let rafId = null;
984
+ function getScrollPercent() {
985
+ const doc = document.documentElement;
986
+ const scrollTop = window.scrollY || doc.scrollTop;
987
+ const scrollHeight = doc.scrollHeight;
988
+ const clientHeight = doc.clientHeight;
989
+ if (scrollHeight <= clientHeight) return 100;
990
+ return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
991
+ }
992
+ function checkThresholds() {
993
+ const percent = getScrollPercent();
994
+ for (const threshold of thresholds) {
995
+ if (percent >= threshold && !firedForPath.has(threshold)) {
996
+ firedForPath.add(threshold);
997
+ client.trackEvent({
998
+ eventType: "scroll_depth",
999
+ metadata: {
1000
+ depth_percent: threshold,
1001
+ page: { path: currentPath }
1002
+ },
1003
+ pageUrl: window.location.href,
1004
+ occurredAt: null
1005
+ });
1006
+ }
1007
+ }
1008
+ }
1009
+ function onScroll() {
1010
+ if (rafId !== null) return;
1011
+ rafId = requestAnimationFrame(() => {
1012
+ rafId = null;
1013
+ checkThresholds();
765
1014
  });
766
1015
  }
1016
+ function resetIfPathChanged() {
1017
+ const newPath = window.location.pathname;
1018
+ if (newPath === currentPath) return;
1019
+ currentPath = newPath;
1020
+ firedForPath = /* @__PURE__ */ new Set();
1021
+ setTimeout(checkThresholds, 0);
1022
+ }
1023
+ const originalPushState = history.pushState.bind(history);
1024
+ const originalReplaceState = history.replaceState.bind(history);
1025
+ function patchedPushState(...args) {
1026
+ originalPushState(...args);
1027
+ setTimeout(resetIfPathChanged, 0);
1028
+ }
1029
+ function patchedReplaceState(...args) {
1030
+ originalReplaceState(...args);
1031
+ setTimeout(resetIfPathChanged, 0);
1032
+ }
1033
+ history.pushState = patchedPushState;
1034
+ history.replaceState = patchedReplaceState;
1035
+ window.addEventListener("popstate", resetIfPathChanged);
1036
+ window.addEventListener("scroll", onScroll, { passive: true });
1037
+ setTimeout(checkThresholds, 0);
1038
+ return () => {
1039
+ if (rafId !== null) cancelAnimationFrame(rafId);
1040
+ history.pushState = originalPushState;
1041
+ history.replaceState = originalReplaceState;
1042
+ window.removeEventListener("popstate", resetIfPathChanged);
1043
+ window.removeEventListener("scroll", onScroll);
1044
+ };
1045
+ }
1046
+
1047
+ // ../tracking-core/src/triggers/multi-page-session.ts
1048
+ var STORAGE_KEY = "aranova_tracking_mps_paths";
1049
+ var SESSION_KEY = "aranova_tracking_mps_session";
1050
+ var FIRED_KEY = "aranova_tracking_mps_fired";
1051
+ function getSessionStorage() {
1052
+ try {
1053
+ return typeof window !== "undefined" ? window.sessionStorage : null;
1054
+ } catch {
1055
+ return null;
1056
+ }
1057
+ }
1058
+ function attachMultiPageSession(client, config) {
1059
+ if (typeof window === "undefined" || typeof history === "undefined") {
1060
+ return () => {
1061
+ };
1062
+ }
1063
+ const storage = getSessionStorage();
1064
+ if (!storage) return () => {
1065
+ };
1066
+ const { pageThreshold } = config;
1067
+ let lastCheckedPath = "";
1068
+ function getDistinctPaths() {
1069
+ try {
1070
+ const raw = storage.getItem(STORAGE_KEY);
1071
+ return raw ? new Set(JSON.parse(raw)) : /* @__PURE__ */ new Set();
1072
+ } catch {
1073
+ return /* @__PURE__ */ new Set();
1074
+ }
1075
+ }
1076
+ function saveDistinctPaths(paths) {
1077
+ try {
1078
+ storage.setItem(STORAGE_KEY, JSON.stringify([...paths]));
1079
+ } catch {
1080
+ }
1081
+ }
1082
+ function resetIfSessionChanged() {
1083
+ const currentSession = getOrRotateSessionId().id;
1084
+ const storedSession = storage.getItem(SESSION_KEY);
1085
+ if (storedSession !== currentSession) {
1086
+ storage.setItem(SESSION_KEY, currentSession);
1087
+ storage.removeItem(STORAGE_KEY);
1088
+ storage.removeItem(FIRED_KEY);
1089
+ }
1090
+ }
1091
+ function hasFired() {
1092
+ return storage.getItem(FIRED_KEY) === "1";
1093
+ }
1094
+ function check() {
1095
+ const currentPath = window.location.pathname;
1096
+ if (currentPath === lastCheckedPath) return;
1097
+ lastCheckedPath = currentPath;
1098
+ resetIfSessionChanged();
1099
+ if (hasFired()) return;
1100
+ const paths = getDistinctPaths();
1101
+ paths.add(currentPath);
1102
+ saveDistinctPaths(paths);
1103
+ if (paths.size >= pageThreshold) {
1104
+ storage.setItem(FIRED_KEY, "1");
1105
+ client.trackEvent({
1106
+ eventType: "multi_page_session",
1107
+ metadata: {
1108
+ page_count: paths.size,
1109
+ page: { path: window.location.pathname }
1110
+ },
1111
+ pageUrl: window.location.href,
1112
+ occurredAt: null
1113
+ });
1114
+ }
1115
+ }
767
1116
  const originalPushState = history.pushState.bind(history);
768
1117
  const originalReplaceState = history.replaceState.bind(history);
769
1118
  function patchedPushState(...args) {
@@ -785,6 +1134,71 @@ function attachContactPageVisit(client, config) {
785
1134
  };
786
1135
  }
787
1136
 
1137
+ // ../tracking-core/src/triggers/form-start.ts
1138
+ function attachFormStart(client, config) {
1139
+ if (typeof window === "undefined" || typeof document === "undefined") {
1140
+ return () => {
1141
+ };
1142
+ }
1143
+ const selector = config.selector ?? "form";
1144
+ let firedForms = /* @__PURE__ */ new Set();
1145
+ let currentPath = window.location.pathname;
1146
+ function getFormKey(form) {
1147
+ if (form.id) return `id:${form.id}`;
1148
+ const explicitAction = form.getAttribute("action");
1149
+ if (explicitAction) return `action:${explicitAction}`;
1150
+ const forms = Array.from(document.querySelectorAll(selector));
1151
+ return `index:${forms.indexOf(form)}`;
1152
+ }
1153
+ function onFocusIn(event) {
1154
+ const target = event.target;
1155
+ if (!(target instanceof HTMLElement)) return;
1156
+ const form = target.closest(selector);
1157
+ if (!form || form.tagName !== "FORM") return;
1158
+ const key = getFormKey(form);
1159
+ if (firedForms.has(key)) return;
1160
+ firedForms.add(key);
1161
+ client.trackEvent({
1162
+ eventType: "form_start",
1163
+ metadata: {
1164
+ form: {
1165
+ id: form.id || "",
1166
+ action: form.getAttribute("action") ?? null
1167
+ },
1168
+ page: { path: window.location.pathname }
1169
+ },
1170
+ pageUrl: window.location.href,
1171
+ occurredAt: null
1172
+ });
1173
+ }
1174
+ function resetIfPathChanged() {
1175
+ const newPath = window.location.pathname;
1176
+ if (newPath === currentPath) return;
1177
+ currentPath = newPath;
1178
+ firedForms = /* @__PURE__ */ new Set();
1179
+ }
1180
+ const originalPushState = history.pushState.bind(history);
1181
+ const originalReplaceState = history.replaceState.bind(history);
1182
+ function patchedPushState(...args) {
1183
+ originalPushState(...args);
1184
+ setTimeout(resetIfPathChanged, 0);
1185
+ }
1186
+ function patchedReplaceState(...args) {
1187
+ originalReplaceState(...args);
1188
+ setTimeout(resetIfPathChanged, 0);
1189
+ }
1190
+ history.pushState = patchedPushState;
1191
+ history.replaceState = patchedReplaceState;
1192
+ window.addEventListener("popstate", resetIfPathChanged);
1193
+ document.addEventListener("focusin", onFocusIn);
1194
+ return () => {
1195
+ history.pushState = originalPushState;
1196
+ history.replaceState = originalReplaceState;
1197
+ window.removeEventListener("popstate", resetIfPathChanged);
1198
+ document.removeEventListener("focusin", onFocusIn);
1199
+ };
1200
+ }
1201
+
788
1202
  // src/ConsentBanner.tsx
789
1203
  import { jsx, jsxs } from "react/jsx-runtime";
790
1204
  function ConsentBanner() {
@@ -879,7 +1293,7 @@ import {
879
1293
  } from "react";
880
1294
 
881
1295
  // package.json
882
- var version = "0.4.2";
1296
+ var version = "0.5.1";
883
1297
 
884
1298
  // src/factory.tsx
885
1299
  import { jsx as jsx2 } from "react/jsx-runtime";
@@ -915,6 +1329,7 @@ function createTracking(options) {
915
1329
  surface: "react",
916
1330
  packageName: "@aranova/tracking-react",
917
1331
  sdkVersion: version,
1332
+ triggers,
918
1333
  debug
919
1334
  }),
920
1335
  triggers,
@@ -933,6 +1348,7 @@ function createTracking(options) {
933
1348
  endpoint,
934
1349
  surface: "react",
935
1350
  packageName: "@aranova/tracking-react",
1351
+ triggers,
936
1352
  debug
937
1353
  });
938
1354
  detachers.push(attachAutoPageView(rawClient));
@@ -941,9 +1357,21 @@ function createTracking(options) {
941
1357
  if (timeOnSite) {
942
1358
  detachers.push(attachTimeOnSite(rawClient, timeOnSite));
943
1359
  }
944
- const contactPageVisit = triggers.automatic.contact_page_visit;
945
- if (contactPageVisit) {
946
- detachers.push(attachContactPageVisit(rawClient, contactPageVisit));
1360
+ const specificPageVisit = triggers.automatic.specific_page_visit;
1361
+ if (specificPageVisit) {
1362
+ detachers.push(attachSpecificPageVisit(rawClient, specificPageVisit));
1363
+ }
1364
+ const scrollDepth = triggers.automatic.scroll_depth;
1365
+ if (scrollDepth) {
1366
+ detachers.push(attachScrollDepth(rawClient, scrollDepth));
1367
+ }
1368
+ const multiPageSession = triggers.automatic.multi_page_session;
1369
+ if (multiPageSession) {
1370
+ detachers.push(attachMultiPageSession(rawClient, multiPageSession));
1371
+ }
1372
+ const formStart = triggers.automatic.form_start;
1373
+ if (formStart) {
1374
+ detachers.push(attachFormStart(rawClient, formStart));
947
1375
  }
948
1376
  return () => {
949
1377
  for (let i = detachers.length - 1; i >= 0; i--) {