@neowhale/storefront 0.2.30 → 0.2.32

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.
@@ -1,11 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
- import { F as WhaleStorefrontConfig, r as Product, P as PaymentData, O as Order, a as CartItem, T as TaxBreakdown, W as WhaleClient, f as Customer, E as EventType, g as CustomerAnalytics, d as CheckoutSession, A as Address, b as Category, c as CategoryTreeNode, l as LoyaltyAccount, m as LoyaltyReward, n as LoyaltyTransaction, v as Review, w as ReviewSummary, G as WishlistItem, R as Recommendation, k as Location, x as ShippingMethod, y as ShippingRate, D as DealValidation, C as Cart, H as ReferralStatus, I as ReferralEnrollment, i as LandingSection, Q as QRLandingData, h as LandingPageRenderData } from '../client-CwCSPAHp.cjs';
4
+ import { F as WhaleStorefrontConfig, r as Product, P as PaymentData, O as Order, a as CartItem, T as TaxBreakdown, W as WhaleClient, f as Customer, E as EventType, g as CustomerAnalytics, d as CheckoutSession, A as Address, b as Category, c as CategoryTreeNode, l as LoyaltyAccount, m as LoyaltyReward, n as LoyaltyTransaction, v as Review, w as ReviewSummary, G as WishlistItem, R as Recommendation, k as Location, x as ShippingMethod, y as ShippingRate, D as DealValidation, C as Cart, H as ReferralStatus, I as ReferralEnrollment, i as LandingSection, Q as QRLandingData, h as LandingPageRenderData } from '../client-CUKv5fMM.cjs';
5
5
  import { ThemeTokens } from '@neowhale/ui';
6
6
  import * as zustand_middleware from 'zustand/middleware';
7
7
  import * as zustand from 'zustand';
8
- import { P as PixelManager } from '../pixel-manager-ti1xc1eC.cjs';
8
+ import { P as PixelManager } from '../pixel-manager-oZStK6GU.cjs';
9
9
 
10
10
  interface WhaleProviderProps extends WhaleStorefrontConfig {
11
11
  children: ReactNode;
@@ -236,6 +236,8 @@ declare function useAnalytics(): {
236
236
  trackingEnabled: boolean;
237
237
  /** Configured recording sample rate (0–1) for behavioral session replays */
238
238
  recordingRate: number;
239
+ /** Stable visitor ID for cross-session attribution */
240
+ visitorId: string;
239
241
  };
240
242
 
241
243
  declare function useWhaleClient(): WhaleClient;
@@ -430,8 +432,12 @@ interface LandingPageProps {
430
432
  onDataLoaded?: (data: LandingPageRenderData) => void;
431
433
  onError?: (error: Error) => void;
432
434
  onEvent?: (event: string, data: Record<string, unknown>) => void;
435
+ analyticsContext?: {
436
+ visitorId?: string;
437
+ sessionId?: string;
438
+ };
433
439
  }
434
- declare function LandingPage({ slug, gatewayUrl, renderSection, onDataLoaded, onError, onEvent, }: LandingPageProps): react_jsx_runtime.JSX.Element | null;
440
+ declare function LandingPage({ slug, gatewayUrl, renderSection, onDataLoaded, onError, onEvent, analyticsContext, }: LandingPageProps): react_jsx_runtime.JSX.Element | null;
435
441
 
436
442
  interface SectionTheme {
437
443
  bg: string;
@@ -1,11 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
- import { F as WhaleStorefrontConfig, r as Product, P as PaymentData, O as Order, a as CartItem, T as TaxBreakdown, W as WhaleClient, f as Customer, E as EventType, g as CustomerAnalytics, d as CheckoutSession, A as Address, b as Category, c as CategoryTreeNode, l as LoyaltyAccount, m as LoyaltyReward, n as LoyaltyTransaction, v as Review, w as ReviewSummary, G as WishlistItem, R as Recommendation, k as Location, x as ShippingMethod, y as ShippingRate, D as DealValidation, C as Cart, H as ReferralStatus, I as ReferralEnrollment, i as LandingSection, Q as QRLandingData, h as LandingPageRenderData } from '../client-CwCSPAHp.js';
4
+ import { F as WhaleStorefrontConfig, r as Product, P as PaymentData, O as Order, a as CartItem, T as TaxBreakdown, W as WhaleClient, f as Customer, E as EventType, g as CustomerAnalytics, d as CheckoutSession, A as Address, b as Category, c as CategoryTreeNode, l as LoyaltyAccount, m as LoyaltyReward, n as LoyaltyTransaction, v as Review, w as ReviewSummary, G as WishlistItem, R as Recommendation, k as Location, x as ShippingMethod, y as ShippingRate, D as DealValidation, C as Cart, H as ReferralStatus, I as ReferralEnrollment, i as LandingSection, Q as QRLandingData, h as LandingPageRenderData } from '../client-CUKv5fMM.js';
5
5
  import { ThemeTokens } from '@neowhale/ui';
6
6
  import * as zustand_middleware from 'zustand/middleware';
7
7
  import * as zustand from 'zustand';
8
- import { P as PixelManager } from '../pixel-manager-LiLpBmPy.js';
8
+ import { P as PixelManager } from '../pixel-manager-DsrUxlIB.js';
9
9
 
10
10
  interface WhaleProviderProps extends WhaleStorefrontConfig {
11
11
  children: ReactNode;
@@ -236,6 +236,8 @@ declare function useAnalytics(): {
236
236
  trackingEnabled: boolean;
237
237
  /** Configured recording sample rate (0–1) for behavioral session replays */
238
238
  recordingRate: number;
239
+ /** Stable visitor ID for cross-session attribution */
240
+ visitorId: string;
239
241
  };
240
242
 
241
243
  declare function useWhaleClient(): WhaleClient;
@@ -430,8 +432,12 @@ interface LandingPageProps {
430
432
  onDataLoaded?: (data: LandingPageRenderData) => void;
431
433
  onError?: (error: Error) => void;
432
434
  onEvent?: (event: string, data: Record<string, unknown>) => void;
435
+ analyticsContext?: {
436
+ visitorId?: string;
437
+ sessionId?: string;
438
+ };
433
439
  }
434
- declare function LandingPage({ slug, gatewayUrl, renderSection, onDataLoaded, onError, onEvent, }: LandingPageProps): react_jsx_runtime.JSX.Element | null;
440
+ declare function LandingPage({ slug, gatewayUrl, renderSection, onDataLoaded, onError, onEvent, analyticsContext, }: LandingPageProps): react_jsx_runtime.JSX.Element | null;
435
441
 
436
442
  interface SectionTheme {
437
443
  bg: string;
@@ -1,5 +1,5 @@
1
1
  import { PixelManager } from '../chunk-MZO7BCGU.js';
2
- import { resilientSend, WhaleClient } from '../chunk-WNZOA4FB.js';
2
+ import { resilientSend, WhaleClient } from '../chunk-2XODSXJT.js';
3
3
  import { createContext, useContext, useRef, useCallback, useEffect, useState, useMemo } from 'react';
4
4
  import { usePathname } from 'next/navigation';
5
5
  import { createStore } from 'zustand/vanilla';
@@ -553,7 +553,9 @@ function useAnalytics() {
553
553
  /** Whether tracking is globally enabled for this storefront */
554
554
  trackingEnabled,
555
555
  /** Configured recording sample rate (0–1) for behavioral session replays */
556
- recordingRate: config.recordingRate
556
+ recordingRate: config.recordingRate,
557
+ /** Stable visitor ID for cross-session attribution */
558
+ visitorId: getVisitorId(config.storagePrefix)
557
559
  };
558
560
  }
559
561
  function useAuth() {
@@ -1864,6 +1866,7 @@ function useCustomerAnalytics() {
1864
1866
  function useCheckout() {
1865
1867
  const ctx = useContext(WhaleContext);
1866
1868
  if (!ctx) throw new Error("useCheckout must be used within <WhaleProvider>");
1869
+ const { visitorId, getOrCreateSession: getAnalyticsSession } = useAnalytics();
1867
1870
  const [session, setSession] = useState(null);
1868
1871
  const [loading, setLoading] = useState(false);
1869
1872
  const [error, setError] = useState(null);
@@ -1871,7 +1874,12 @@ function useCheckout() {
1871
1874
  setLoading(true);
1872
1875
  setError(null);
1873
1876
  try {
1874
- const data = await ctx.client.createCheckoutSession(params);
1877
+ const analyticsSessionId = await getAnalyticsSession().catch(() => void 0);
1878
+ const data = await ctx.client.createCheckoutSession({
1879
+ ...params,
1880
+ visitor_id: visitorId,
1881
+ session_id: analyticsSessionId?.startsWith("local-") ? void 0 : analyticsSessionId
1882
+ });
1875
1883
  setSession(data);
1876
1884
  return data;
1877
1885
  } catch (err) {
@@ -2900,6 +2908,8 @@ function LeadCaptureSection({ section, data, theme, onEvent }) {
2900
2908
  if (!email || !storeId) return;
2901
2909
  setStatus("loading");
2902
2910
  setErrorMsg("");
2911
+ const urlParams = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : null;
2912
+ const analyticsData = data.analyticsContext;
2903
2913
  try {
2904
2914
  const res = await fetch(`${gatewayUrl}/v1/stores/${storeId}/storefront/leads`, {
2905
2915
  method: "POST",
@@ -2914,7 +2924,13 @@ function LeadCaptureSection({ section, data, theme, onEvent }) {
2914
2924
  const t = [...c.tags || []];
2915
2925
  if (newsletterOptIn) t.push(c.newsletter_tag || "newsletter-subscriber");
2916
2926
  return t.length > 0 ? t : void 0;
2917
- })()
2927
+ })(),
2928
+ visitor_id: analyticsData?.visitorId || void 0,
2929
+ session_id: analyticsData?.sessionId || void 0,
2930
+ utm_source: urlParams?.get("utm_source") || void 0,
2931
+ utm_medium: urlParams?.get("utm_medium") || void 0,
2932
+ utm_campaign: urlParams?.get("utm_campaign") || void 0,
2933
+ utm_content: urlParams?.get("utm_content") || void 0
2918
2934
  })
2919
2935
  });
2920
2936
  if (!res.ok) {
@@ -3460,7 +3476,8 @@ function LandingPage({
3460
3476
  renderSection,
3461
3477
  onDataLoaded,
3462
3478
  onError,
3463
- onEvent
3479
+ onEvent,
3480
+ analyticsContext
3464
3481
  }) {
3465
3482
  const [state, setState] = useState("loading");
3466
3483
  const [data, setData] = useState(null);
@@ -3508,13 +3525,14 @@ function LandingPage({
3508
3525
  if (state === "expired") return /* @__PURE__ */ jsx(DefaultExpired2, {});
3509
3526
  if (state === "error") return /* @__PURE__ */ jsx(DefaultError2, { message: errorMsg });
3510
3527
  if (!data) return null;
3511
- return /* @__PURE__ */ jsx(PageLayout, { data, gatewayUrl, renderSection, onEvent });
3528
+ return /* @__PURE__ */ jsx(PageLayout, { data, gatewayUrl, renderSection, onEvent, analyticsContext });
3512
3529
  }
3513
3530
  function PageLayout({
3514
3531
  data,
3515
3532
  gatewayUrl,
3516
3533
  renderSection,
3517
- onEvent
3534
+ onEvent,
3535
+ analyticsContext
3518
3536
  }) {
3519
3537
  const { landing_page: lp, store } = data;
3520
3538
  const theme = {
@@ -3529,7 +3547,7 @@ function PageLayout({
3529
3547
  const fontFamily = lp.font_family || theme.fontDisplay || "system-ui, -apple-system, sans-serif";
3530
3548
  const logoUrl = store?.logo_url;
3531
3549
  const sorted = [...lp.sections].sort((a, b) => a.order - b.order);
3532
- const sectionData = { ...data, gatewayUrl, landing_page: { slug: lp.slug } };
3550
+ const sectionData = { ...data, gatewayUrl, landing_page: { slug: lp.slug }, analyticsContext };
3533
3551
  return /* @__PURE__ */ jsxs("div", { style: { minHeight: "100dvh", background: theme.bg, color: theme.fg, fontFamily }, children: [
3534
3552
  lp.custom_css && /* @__PURE__ */ jsx("style", { children: lp.custom_css }),
3535
3553
  logoUrl && /* @__PURE__ */ jsx("div", { style: { padding: "1.5rem", display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx("img", { src: logoUrl, alt: store?.name || "Store", style: { height: 40, objectFit: "contain" } }) }),