@nexushub/client 0.2.9 → 0.3.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.cjs CHANGED
@@ -1626,6 +1626,7 @@ var AnalyticsEngine = class {
1626
1626
  constructor(config) {
1627
1627
  this.cleanupFns = [];
1628
1628
  this.isInitialized = false;
1629
+ this.lastPath = typeof window !== "undefined" ? window.location.pathname : "";
1629
1630
  this.tracker = new Tracker(config);
1630
1631
  }
1631
1632
  start() {
@@ -1641,14 +1642,18 @@ var AnalyticsEngine = class {
1641
1642
  console.log("[NexusHub] \u{1F680} Analytics Engine Started");
1642
1643
  }
1643
1644
  }
1644
- pageView() {
1645
+ pageView(customReferrer) {
1645
1646
  if (typeof window === "undefined") return;
1647
+ const currentPath = window.location.pathname;
1646
1648
  this.tracker.send("page_view", {
1647
- path: window.location.pathname,
1649
+ path: currentPath,
1648
1650
  search: window.location.search,
1649
1651
  title: document.title,
1650
- timezone_offset: (/* @__PURE__ */ new Date()).getTimezoneOffset()
1652
+ timezone_offset: (/* @__PURE__ */ new Date()).getTimezoneOffset(),
1653
+ // Use the virtual path as referrer if navigating internally
1654
+ referrer: customReferrer || (this.lastPath !== currentPath ? this.lastPath : document.referrer)
1651
1655
  });
1656
+ this.lastPath = currentPath;
1652
1657
  }
1653
1658
  // --- SOCIAL / DARK SOCIAL TRACKING ---
1654
1659
  setupShareTracking() {
@@ -1775,7 +1780,8 @@ var AnalyticsEngine = class {
1775
1780
  text: _optionalChain([link, 'access', _29 => _29.innerText, 'optionalAccess', _30 => _30.substring, 'call', _31 => _31(0, 50)]),
1776
1781
  id: link.id,
1777
1782
  classes: link.className,
1778
- dataset: { ...link.dataset }
1783
+ dataset: { ...link.dataset },
1784
+ coordinates: { x: e.clientX, y: e.clientY }
1779
1785
  });
1780
1786
  }
1781
1787
  const button = target.closest("button");
@@ -1818,13 +1824,20 @@ var AnalyticsEngine = class {
1818
1824
  const originalPushState = history.pushState.bind(history);
1819
1825
  const originalReplaceState = history.replaceState.bind(history);
1820
1826
  history.pushState = (...args) => {
1827
+ const prevPath = window.location.pathname;
1821
1828
  originalPushState(...args);
1822
- this.pageView();
1829
+ if (!this.isInitializedByReactProvider()) {
1830
+ this.pageView(prevPath);
1831
+ }
1823
1832
  };
1824
1833
  history.replaceState = (...args) => {
1825
1834
  originalReplaceState(...args);
1826
1835
  };
1827
- const popStateHandler = () => this.pageView();
1836
+ const popStateHandler = () => {
1837
+ if (!this.isInitializedByReactProvider()) {
1838
+ this.pageView();
1839
+ }
1840
+ };
1828
1841
  window.addEventListener("popstate", popStateHandler);
1829
1842
  this.cleanupFns.push(() => {
1830
1843
  history.pushState = originalPushState;
@@ -1832,16 +1845,22 @@ var AnalyticsEngine = class {
1832
1845
  window.removeEventListener("popstate", popStateHandler);
1833
1846
  });
1834
1847
  }
1848
+ // Simple flag to check if NexusProvider is active
1849
+ isInitializedByReactProvider() {
1850
+ return !!document.getElementById("__nexus_react_active");
1851
+ }
1835
1852
  getSessionId() {
1836
1853
  return this.tracker.getSession();
1837
1854
  }
1838
- stop() {
1855
+ stop(isFinalShutdown = false) {
1839
1856
  this.cleanupFns.forEach((fn) => fn());
1840
1857
  this.cleanupFns = [];
1841
- this.tracker.send("session_end", {
1842
- session_id: this.tracker.getSession(),
1843
- duration: this.tracker.getSessionDuration()
1844
- });
1858
+ if (isFinalShutdown) {
1859
+ this.tracker.send("session_end", {
1860
+ session_id: this.tracker.getSession(),
1861
+ duration: this.tracker.getSessionDuration()
1862
+ });
1863
+ }
1845
1864
  this.tracker.stop();
1846
1865
  this.isInitialized = false;
1847
1866
  }
@@ -2109,13 +2128,15 @@ function NexusAnalyticsTracker({
2109
2128
  }) {
2110
2129
  const pathname = _navigation.usePathname.call(void 0, );
2111
2130
  const searchParams = _navigation.useSearchParams.call(void 0, );
2131
+ const prevPathRef = _react.useRef.call(void 0, "");
2112
2132
  const searchParamsString = searchParams.toString();
2113
2133
  _react.useEffect.call(void 0, () => {
2114
2134
  if (nexus.analytics && !disableAnalytics) {
2115
- nexus.analytics.pageView();
2135
+ nexus.analytics.pageView(prevPathRef.current || document.referrer);
2136
+ prevPathRef.current = pathname;
2116
2137
  }
2117
2138
  }, [pathname, searchParamsString, disableAnalytics]);
2118
- return null;
2139
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { id: "__nexus_react_active", style: { display: "none" } });
2119
2140
  }
2120
2141
  var NexusProvider = ({
2121
2142
  children,
package/dist/index.d.cts CHANGED
@@ -220,7 +220,8 @@ declare class AnalyticsEngine {
220
220
  private isInitialized;
221
221
  constructor(config: NexusConfig);
222
222
  start(): void;
223
- pageView(): void;
223
+ private lastPath;
224
+ pageView(customReferrer?: string): void;
224
225
  private setupShareTracking;
225
226
  identify(userId: string, traits?: Record<string, any>): Promise<boolean>;
226
227
  group(groupId: string, traits?: Record<string, any>): Promise<boolean>;
@@ -242,8 +243,9 @@ declare class AnalyticsEngine {
242
243
  private setupClickTracking;
243
244
  private setupFormTracking;
244
245
  private setupRouteTracking;
246
+ private isInitializedByReactProvider;
245
247
  getSessionId(): string;
246
- stop(): void;
248
+ stop(isFinalShutdown?: boolean): void;
247
249
  }
248
250
 
249
251
  declare class NexusClient {
package/dist/index.d.ts CHANGED
@@ -220,7 +220,8 @@ declare class AnalyticsEngine {
220
220
  private isInitialized;
221
221
  constructor(config: NexusConfig);
222
222
  start(): void;
223
- pageView(): void;
223
+ private lastPath;
224
+ pageView(customReferrer?: string): void;
224
225
  private setupShareTracking;
225
226
  identify(userId: string, traits?: Record<string, any>): Promise<boolean>;
226
227
  group(groupId: string, traits?: Record<string, any>): Promise<boolean>;
@@ -242,8 +243,9 @@ declare class AnalyticsEngine {
242
243
  private setupClickTracking;
243
244
  private setupFormTracking;
244
245
  private setupRouteTracking;
246
+ private isInitializedByReactProvider;
245
247
  getSessionId(): string;
246
- stop(): void;
248
+ stop(isFinalShutdown?: boolean): void;
247
249
  }
248
250
 
249
251
  declare class NexusClient {
package/dist/index.js CHANGED
@@ -1626,6 +1626,7 @@ var AnalyticsEngine = class {
1626
1626
  constructor(config) {
1627
1627
  this.cleanupFns = [];
1628
1628
  this.isInitialized = false;
1629
+ this.lastPath = typeof window !== "undefined" ? window.location.pathname : "";
1629
1630
  this.tracker = new Tracker(config);
1630
1631
  }
1631
1632
  start() {
@@ -1641,14 +1642,18 @@ var AnalyticsEngine = class {
1641
1642
  console.log("[NexusHub] \u{1F680} Analytics Engine Started");
1642
1643
  }
1643
1644
  }
1644
- pageView() {
1645
+ pageView(customReferrer) {
1645
1646
  if (typeof window === "undefined") return;
1647
+ const currentPath = window.location.pathname;
1646
1648
  this.tracker.send("page_view", {
1647
- path: window.location.pathname,
1649
+ path: currentPath,
1648
1650
  search: window.location.search,
1649
1651
  title: document.title,
1650
- timezone_offset: (/* @__PURE__ */ new Date()).getTimezoneOffset()
1652
+ timezone_offset: (/* @__PURE__ */ new Date()).getTimezoneOffset(),
1653
+ // Use the virtual path as referrer if navigating internally
1654
+ referrer: customReferrer || (this.lastPath !== currentPath ? this.lastPath : document.referrer)
1651
1655
  });
1656
+ this.lastPath = currentPath;
1652
1657
  }
1653
1658
  // --- SOCIAL / DARK SOCIAL TRACKING ---
1654
1659
  setupShareTracking() {
@@ -1775,7 +1780,8 @@ var AnalyticsEngine = class {
1775
1780
  text: link.innerText?.substring(0, 50),
1776
1781
  id: link.id,
1777
1782
  classes: link.className,
1778
- dataset: { ...link.dataset }
1783
+ dataset: { ...link.dataset },
1784
+ coordinates: { x: e.clientX, y: e.clientY }
1779
1785
  });
1780
1786
  }
1781
1787
  const button = target.closest("button");
@@ -1818,13 +1824,20 @@ var AnalyticsEngine = class {
1818
1824
  const originalPushState = history.pushState.bind(history);
1819
1825
  const originalReplaceState = history.replaceState.bind(history);
1820
1826
  history.pushState = (...args) => {
1827
+ const prevPath = window.location.pathname;
1821
1828
  originalPushState(...args);
1822
- this.pageView();
1829
+ if (!this.isInitializedByReactProvider()) {
1830
+ this.pageView(prevPath);
1831
+ }
1823
1832
  };
1824
1833
  history.replaceState = (...args) => {
1825
1834
  originalReplaceState(...args);
1826
1835
  };
1827
- const popStateHandler = () => this.pageView();
1836
+ const popStateHandler = () => {
1837
+ if (!this.isInitializedByReactProvider()) {
1838
+ this.pageView();
1839
+ }
1840
+ };
1828
1841
  window.addEventListener("popstate", popStateHandler);
1829
1842
  this.cleanupFns.push(() => {
1830
1843
  history.pushState = originalPushState;
@@ -1832,16 +1845,22 @@ var AnalyticsEngine = class {
1832
1845
  window.removeEventListener("popstate", popStateHandler);
1833
1846
  });
1834
1847
  }
1848
+ // Simple flag to check if NexusProvider is active
1849
+ isInitializedByReactProvider() {
1850
+ return !!document.getElementById("__nexus_react_active");
1851
+ }
1835
1852
  getSessionId() {
1836
1853
  return this.tracker.getSession();
1837
1854
  }
1838
- stop() {
1855
+ stop(isFinalShutdown = false) {
1839
1856
  this.cleanupFns.forEach((fn) => fn());
1840
1857
  this.cleanupFns = [];
1841
- this.tracker.send("session_end", {
1842
- session_id: this.tracker.getSession(),
1843
- duration: this.tracker.getSessionDuration()
1844
- });
1858
+ if (isFinalShutdown) {
1859
+ this.tracker.send("session_end", {
1860
+ session_id: this.tracker.getSession(),
1861
+ duration: this.tracker.getSessionDuration()
1862
+ });
1863
+ }
1845
1864
  this.tracker.stop();
1846
1865
  this.isInitialized = false;
1847
1866
  }
@@ -2109,13 +2128,15 @@ function NexusAnalyticsTracker({
2109
2128
  }) {
2110
2129
  const pathname = usePathname();
2111
2130
  const searchParams = useSearchParams();
2131
+ const prevPathRef = useRef("");
2112
2132
  const searchParamsString = searchParams.toString();
2113
2133
  useEffect2(() => {
2114
2134
  if (nexus.analytics && !disableAnalytics) {
2115
- nexus.analytics.pageView();
2135
+ nexus.analytics.pageView(prevPathRef.current || document.referrer);
2136
+ prevPathRef.current = pathname;
2116
2137
  }
2117
2138
  }, [pathname, searchParamsString, disableAnalytics]);
2118
- return null;
2139
+ return /* @__PURE__ */ jsx2("div", { id: "__nexus_react_active", style: { display: "none" } });
2119
2140
  }
2120
2141
  var NexusProvider = ({
2121
2142
  children,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nexushub/client",
3
3
  "private": false,
4
- "version": "0.2.9",
4
+ "version": "0.3.0",
5
5
  "description": "The God-Tier NexusHub SDK",
6
6
  "type": "module",
7
7
  "main": "./dist/index.cjs",