@neowhale/storefront 0.1.2 → 0.2.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/README.md +1 -1
- package/dist/chunk-CUVDHOQ4.js +90 -0
- package/dist/chunk-CUVDHOQ4.js.map +1 -0
- package/dist/chunk-DAM7NZCI.cjs +92 -0
- package/dist/chunk-DAM7NZCI.cjs.map +1 -0
- package/dist/chunk-OP4LOUCV.cjs +291 -0
- package/dist/chunk-OP4LOUCV.cjs.map +1 -0
- package/dist/chunk-QIIKQ7DN.js +288 -0
- package/dist/chunk-QIIKQ7DN.js.map +1 -0
- package/dist/client-y0V1x0px.d.cts +305 -0
- package/dist/client-y0V1x0px.d.ts +305 -0
- package/dist/index.cjs +11 -2
- package/dist/index.d.cts +14 -267
- package/dist/index.d.ts +14 -267
- package/dist/index.js +2 -1
- package/dist/next/index.cjs +7 -7
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +1 -1
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +4 -4
- package/dist/next/index.js.map +1 -1
- package/dist/pixel-manager-CYtRIGo0.d.ts +10 -0
- package/dist/pixel-manager-Db6Czwr2.d.cts +10 -0
- package/dist/react/index.cjs +69 -13
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +25 -3
- package/dist/react/index.d.ts +25 -3
- package/dist/react/index.js +69 -14
- package/dist/react/index.js.map +1 -1
- package/package.json +8 -1
- package/dist/chunk-PR4PUHVN.js +0 -273
- package/dist/chunk-PR4PUHVN.js.map +0 -1
- package/dist/chunk-XMLH3TLA.cjs +0 -275
- package/dist/chunk-XMLH3TLA.cjs.map +0 -1
package/dist/react/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { PixelManager } from '../chunk-CUVDHOQ4.js';
|
|
2
|
+
import { WhaleClient } from '../chunk-QIIKQ7DN.js';
|
|
3
|
+
import { createContext, useContext, useRef, useCallback, useEffect, useState, useMemo } from 'react';
|
|
3
4
|
import { usePathname } from 'next/navigation';
|
|
4
5
|
import { createStore } from 'zustand/vanilla';
|
|
5
6
|
import { persist } from 'zustand/middleware';
|
|
@@ -298,7 +299,7 @@ var SESSION_KEY_SUFFIX = "-analytics-session";
|
|
|
298
299
|
function useAnalytics() {
|
|
299
300
|
const ctx = useContext(WhaleContext);
|
|
300
301
|
if (!ctx) throw new Error("useAnalytics must be used within <WhaleProvider>");
|
|
301
|
-
const { client, config } = ctx;
|
|
302
|
+
const { client, config, pixelManager } = ctx;
|
|
302
303
|
const sessionPromiseRef = useRef(null);
|
|
303
304
|
const sessionKey = `${config.storagePrefix}${SESSION_KEY_SUFFIX}`;
|
|
304
305
|
const getOrCreateSession = useCallback(async () => {
|
|
@@ -336,18 +337,22 @@ function useAnalytics() {
|
|
|
336
337
|
});
|
|
337
338
|
return sessionPromiseRef.current;
|
|
338
339
|
}, [client, config.sessionTtl, sessionKey]);
|
|
340
|
+
const trackingEnabled = config.trackingEnabled;
|
|
339
341
|
const track = useCallback(
|
|
340
342
|
async (eventType, data = {}) => {
|
|
343
|
+
if (!trackingEnabled) return;
|
|
344
|
+
pixelManager?.track(eventType, data);
|
|
341
345
|
try {
|
|
342
346
|
const sessionId = await getOrCreateSession();
|
|
343
347
|
await client.trackEvent({ session_id: sessionId, event_type: eventType, event_data: data });
|
|
344
348
|
} catch {
|
|
345
349
|
}
|
|
346
350
|
},
|
|
347
|
-
[client, getOrCreateSession]
|
|
351
|
+
[client, getOrCreateSession, pixelManager, trackingEnabled]
|
|
348
352
|
);
|
|
349
353
|
const linkCustomer = useCallback(
|
|
350
354
|
async (customerId) => {
|
|
355
|
+
if (!trackingEnabled) return;
|
|
351
356
|
try {
|
|
352
357
|
const sessionId = await getOrCreateSession();
|
|
353
358
|
if (sessionId.startsWith("local-")) return;
|
|
@@ -355,7 +360,7 @@ function useAnalytics() {
|
|
|
355
360
|
} catch {
|
|
356
361
|
}
|
|
357
362
|
},
|
|
358
|
-
[client, getOrCreateSession]
|
|
363
|
+
[client, getOrCreateSession, trackingEnabled]
|
|
359
364
|
);
|
|
360
365
|
const trackPageView = useCallback(
|
|
361
366
|
(url, referrer) => {
|
|
@@ -416,7 +421,11 @@ function useAnalytics() {
|
|
|
416
421
|
trackAddToCart,
|
|
417
422
|
trackRemoveFromCart,
|
|
418
423
|
linkCustomer,
|
|
419
|
-
getOrCreateSession
|
|
424
|
+
getOrCreateSession,
|
|
425
|
+
/** Whether tracking is globally enabled for this storefront */
|
|
426
|
+
trackingEnabled,
|
|
427
|
+
/** Configured recording sample rate (0–1) for behavioral session replays */
|
|
428
|
+
recordingRate: config.recordingRate
|
|
420
429
|
};
|
|
421
430
|
}
|
|
422
431
|
function useAuth() {
|
|
@@ -437,22 +446,26 @@ function useAuth() {
|
|
|
437
446
|
|
|
438
447
|
// src/react/components/analytics-tracker.tsx
|
|
439
448
|
function AnalyticsTracker({ pathname }) {
|
|
449
|
+
const ctx = useContext(WhaleContext);
|
|
440
450
|
const { trackPageView, linkCustomer } = useAnalytics();
|
|
441
451
|
const { customer } = useAuth();
|
|
442
452
|
const prevPathname = useRef(null);
|
|
443
453
|
const linkedCustomerId = useRef(null);
|
|
454
|
+
const trackingEnabled = ctx?.config.trackingEnabled ?? true;
|
|
444
455
|
useEffect(() => {
|
|
456
|
+
if (!trackingEnabled) return;
|
|
445
457
|
if (pathname === prevPathname.current) return;
|
|
446
458
|
const referrer = prevPathname.current || (typeof document !== "undefined" ? document.referrer : "");
|
|
447
459
|
prevPathname.current = pathname;
|
|
448
460
|
trackPageView(pathname, referrer || void 0);
|
|
449
|
-
}, [pathname, trackPageView]);
|
|
461
|
+
}, [pathname, trackPageView, trackingEnabled]);
|
|
450
462
|
useEffect(() => {
|
|
463
|
+
if (!trackingEnabled) return;
|
|
451
464
|
if (customer?.id && customer.id !== linkedCustomerId.current) {
|
|
452
465
|
linkedCustomerId.current = customer.id;
|
|
453
466
|
linkCustomer(customer.id);
|
|
454
467
|
}
|
|
455
|
-
}, [customer?.id, linkCustomer]);
|
|
468
|
+
}, [customer?.id, linkCustomer, trackingEnabled]);
|
|
456
469
|
return null;
|
|
457
470
|
}
|
|
458
471
|
function useCart() {
|
|
@@ -516,6 +529,38 @@ function AuthInitializer() {
|
|
|
516
529
|
}, []);
|
|
517
530
|
return null;
|
|
518
531
|
}
|
|
532
|
+
function PixelInitializer({ onReady }) {
|
|
533
|
+
const ctx = useContext(WhaleContext);
|
|
534
|
+
const initialized = useRef(false);
|
|
535
|
+
useEffect(() => {
|
|
536
|
+
if (!ctx || initialized.current) return;
|
|
537
|
+
if (typeof window === "undefined") return;
|
|
538
|
+
if (!ctx.config.trackingEnabled) return;
|
|
539
|
+
initialized.current = true;
|
|
540
|
+
const { client } = ctx;
|
|
541
|
+
client.fetchStorefrontConfig().then(async (config) => {
|
|
542
|
+
if (!config.pixels || config.pixels.length === 0) return;
|
|
543
|
+
const manager = new PixelManager(config.pixels);
|
|
544
|
+
await manager.initialize();
|
|
545
|
+
onReady(manager);
|
|
546
|
+
}).catch(() => {
|
|
547
|
+
});
|
|
548
|
+
}, [ctx, onReady]);
|
|
549
|
+
return null;
|
|
550
|
+
}
|
|
551
|
+
function envBool(name) {
|
|
552
|
+
if (typeof process === "undefined") return void 0;
|
|
553
|
+
const raw = process.env[name];
|
|
554
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
555
|
+
return raw !== "0" && raw.toLowerCase() !== "false";
|
|
556
|
+
}
|
|
557
|
+
function envNumber(name) {
|
|
558
|
+
if (typeof process === "undefined") return void 0;
|
|
559
|
+
const raw = process.env[name];
|
|
560
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
561
|
+
const n = Number(raw);
|
|
562
|
+
return Number.isFinite(n) ? n : void 0;
|
|
563
|
+
}
|
|
519
564
|
function WhaleProvider({
|
|
520
565
|
children,
|
|
521
566
|
products = [],
|
|
@@ -527,9 +572,15 @@ function WhaleProvider({
|
|
|
527
572
|
supabaseHost,
|
|
528
573
|
storagePrefix,
|
|
529
574
|
sessionTtl,
|
|
530
|
-
debug
|
|
575
|
+
debug,
|
|
576
|
+
trackingEnabled,
|
|
577
|
+
recordingRate
|
|
531
578
|
}) {
|
|
532
579
|
const pathname = usePathname();
|
|
580
|
+
const [pixelManager, setPixelManager] = useState(null);
|
|
581
|
+
const handlePixelReady = useCallback((manager) => {
|
|
582
|
+
setPixelManager(manager);
|
|
583
|
+
}, []);
|
|
533
584
|
const ctx = useMemo(() => {
|
|
534
585
|
const resolvedConfig = {
|
|
535
586
|
storeId,
|
|
@@ -540,7 +591,9 @@ function WhaleProvider({
|
|
|
540
591
|
supabaseHost: supabaseHost || "",
|
|
541
592
|
storagePrefix: storagePrefix || "whale",
|
|
542
593
|
sessionTtl: sessionTtl || 30 * 60 * 1e3,
|
|
543
|
-
debug: debug || false
|
|
594
|
+
debug: debug || false,
|
|
595
|
+
trackingEnabled: trackingEnabled ?? envBool("NEXT_PUBLIC_TRACKING_ENABLED") ?? true,
|
|
596
|
+
recordingRate: recordingRate ?? envNumber("NEXT_PUBLIC_RECORDING_RATE") ?? 0.1
|
|
544
597
|
};
|
|
545
598
|
const client = new WhaleClient({
|
|
546
599
|
storeId,
|
|
@@ -555,17 +608,19 @@ function WhaleProvider({
|
|
|
555
608
|
config: resolvedConfig,
|
|
556
609
|
cartStore,
|
|
557
610
|
authStore,
|
|
558
|
-
products
|
|
611
|
+
products,
|
|
612
|
+
pixelManager: null
|
|
559
613
|
};
|
|
560
614
|
}, [storeId, apiKey]);
|
|
561
615
|
const value = useMemo(
|
|
562
|
-
() => ({ ...ctx, products }),
|
|
563
|
-
[ctx, products]
|
|
616
|
+
() => ({ ...ctx, products, pixelManager }),
|
|
617
|
+
[ctx, products, pixelManager]
|
|
564
618
|
);
|
|
565
619
|
return /* @__PURE__ */ jsxs(WhaleContext.Provider, { value, children: [
|
|
566
620
|
/* @__PURE__ */ jsx(AuthInitializer, {}),
|
|
567
621
|
/* @__PURE__ */ jsx(CartInitializer, {}),
|
|
568
622
|
/* @__PURE__ */ jsx(AnalyticsTracker, { pathname }),
|
|
623
|
+
/* @__PURE__ */ jsx(PixelInitializer, { onReady: handlePixelReady }),
|
|
569
624
|
children
|
|
570
625
|
] });
|
|
571
626
|
}
|
|
@@ -653,6 +708,6 @@ function useCustomerAnalytics() {
|
|
|
653
708
|
return { analytics, loading };
|
|
654
709
|
}
|
|
655
710
|
|
|
656
|
-
export { AnalyticsTracker, AuthInitializer, CartInitializer, WhaleContext, WhaleProvider, useAnalytics, useAuth, useCart, useCartItemCount, useCartTotal, useCustomerAnalytics, useCustomerOrders, useProduct, useProducts, useWhaleClient };
|
|
711
|
+
export { AnalyticsTracker, AuthInitializer, CartInitializer, PixelInitializer, WhaleContext, WhaleProvider, useAnalytics, useAuth, useCart, useCartItemCount, useCartTotal, useCustomerAnalytics, useCustomerOrders, useProduct, useProducts, useWhaleClient };
|
|
657
712
|
//# sourceMappingURL=index.js.map
|
|
658
713
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/context.ts","../../src/react/stores/cart-store.ts","../../src/react/stores/auth-store.ts","../../src/react/hooks/use-analytics.ts","../../src/react/hooks/use-auth.ts","../../src/react/components/analytics-tracker.tsx","../../src/react/hooks/use-cart.ts","../../src/react/components/cart-initializer.tsx","../../src/react/components/auth-initializer.tsx","../../src/react/provider.tsx","../../src/react/hooks/use-products.ts","../../src/react/hooks/use-client.ts","../../src/react/hooks/use-customer.ts"],"names":["createStore","persist","useContext","useRef","useStore","useShallow","useEffect","useMemo","useState","useCallback"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext } from 'react'\nimport type { WhaleClient } from '../client.js'\nimport type { Product } from '../types.js'\nimport type { CartStore } from './stores/cart-store.js'\nimport type { AuthStore } from './stores/auth-store.js'\n\nexport interface WhaleContextValue {\n client: WhaleClient\n config: {\n storeId: string\n apiKey: string\n gatewayUrl: string\n proxyPath: string\n mediaSigningSecret: string\n supabaseHost: string\n storagePrefix: string\n sessionTtl: number\n debug: boolean\n }\n cartStore: CartStore\n authStore: AuthStore\n /** Products fetched server-side and passed via provider */\n products: Product[]\n}\n\nexport const WhaleContext = createContext<WhaleContextValue | null>(null)\n","import { createStore } from 'zustand/vanilla'\nimport { persist } from 'zustand/middleware'\nimport type { WhaleClient } from '../../client.js'\nimport type { Cart, CartItem, TaxBreakdown, PaymentData, Order } from '../../types.js'\n\nexport interface CartState {\n cartId: string | null\n items: CartItem[]\n itemCount: number\n subtotal: number\n taxAmount: number\n total: number\n taxBreakdown: TaxBreakdown[]\n cartOpen: boolean\n cartLoading: boolean\n productImages: Record<string, string>\n addItemInFlight: boolean\n}\n\nexport interface CartActions {\n openCart: () => void\n closeCart: () => void\n toggleCart: () => void\n initCart: () => Promise<void>\n syncCart: () => Promise<void>\n addItem: (\n productId: string,\n quantity: number,\n tier?: string,\n unitPrice?: number,\n imageUrl?: string | null,\n productName?: string\n ) => Promise<void>\n updateQuantity: (itemId: string, quantity: number) => Promise<void>\n removeItem: (itemId: string, productName?: string) => Promise<void>\n clearCart: () => void\n checkout: (customerEmail?: string, payment?: PaymentData) => Promise<Order>\n}\n\nexport type CartStore = ReturnType<typeof createCartStore>\n\nexport function createCartStore(\n client: WhaleClient,\n storagePrefix: string,\n onAddToCart?: (productId: string, productName: string, quantity: number, price: number, tier?: string) => void,\n onRemoveFromCart?: (productId: string, productName: string) => void\n) {\n return createStore<CartState & CartActions>()(\n persist(\n (set, get) => ({\n // ── Initial state ────────────────────────────────────────────────\n cartId: null,\n items: [],\n itemCount: 0,\n subtotal: 0,\n taxAmount: 0,\n total: 0,\n taxBreakdown: [],\n cartOpen: false,\n cartLoading: false,\n productImages: {},\n addItemInFlight: false,\n\n // ── Cart UI ──────────────────────────────────────────────────────\n openCart: () => set({ cartOpen: true }),\n closeCart: () => set({ cartOpen: false }),\n toggleCart: () => set((s) => ({ cartOpen: !s.cartOpen })),\n\n // ── Cart data ────────────────────────────────────────────────────\n initCart: async () => {\n const { cartId, syncCart } = get()\n\n if (cartId) {\n try {\n await syncCart()\n } catch {\n const cart = await client.createCart()\n applyCart(set, get, cart)\n }\n return\n }\n\n try {\n const cart = await client.createCart()\n applyCart(set, get, cart)\n } catch (err) {\n console.error('[whale-storefront] initCart failed:', err)\n }\n },\n\n syncCart: async () => {\n const { cartId, productImages } = get()\n if (!cartId) return\n\n try {\n const cart = await client.getCart(cartId)\n const items = (cart.items ?? []).map((item) => ({\n ...item,\n image_url: item.image_url || productImages[item.product_id] || null,\n }))\n set({\n items,\n itemCount: cart.item_count ?? 0,\n subtotal: cart.subtotal ?? 0,\n taxAmount: cart.tax_amount ?? 0,\n total: cart.total ?? 0,\n taxBreakdown: cart.tax_breakdown ?? [],\n })\n } catch (err) {\n console.error('[whale-storefront] syncCart failed:', err)\n throw err\n }\n },\n\n addItem: async (productId, quantity, tier, unitPrice, imageUrl, productName) => {\n // Race-condition guard: prevent double-click\n if (get().addItemInFlight) return\n set({ cartLoading: true, addItemInFlight: true })\n\n try {\n let { cartId } = get()\n\n if (!cartId) {\n await get().initCart()\n cartId = get().cartId\n }\n\n if (!cartId) throw new Error('Could not initialise cart')\n\n if (imageUrl) {\n set((s) => ({ productImages: { ...s.productImages, [productId]: imageUrl } }))\n }\n\n try {\n await client.addToCart(cartId, productId, quantity, { tier, unitPrice })\n } catch (err: unknown) {\n // Cart expired (404/410) — auto-recover\n const status = (err as { status?: number }).status\n if (status === 404 || status === 410) {\n const newCart = await client.createCart()\n set({ cartId: newCart.id })\n await client.addToCart(newCart.id, productId, quantity, { tier, unitPrice })\n } else {\n throw err\n }\n }\n\n await get().syncCart()\n\n // Analytics callback\n onAddToCart?.(productId, productName || '', quantity, unitPrice || 0, tier)\n } finally {\n set({ cartLoading: false, addItemInFlight: false })\n }\n },\n\n updateQuantity: async (itemId, quantity) => {\n set({ cartLoading: true })\n try {\n const { cartId } = get()\n if (!cartId) return\n await client.updateCartItem(cartId, itemId, quantity)\n await get().syncCart()\n } finally {\n set({ cartLoading: false })\n }\n },\n\n removeItem: async (itemId, productName) => {\n set({ cartLoading: true })\n try {\n const { cartId, items } = get()\n if (!cartId) return\n\n const item = items.find((i) => i.id === itemId)\n await client.removeCartItem(cartId, itemId)\n await get().syncCart()\n\n if (item) {\n onRemoveFromCart?.(item.product_id, productName || item.product_name)\n }\n } finally {\n set({ cartLoading: false })\n }\n },\n\n clearCart: () => {\n set({\n cartId: null,\n items: [],\n itemCount: 0,\n subtotal: 0,\n taxAmount: 0,\n total: 0,\n taxBreakdown: [],\n productImages: {},\n })\n },\n\n checkout: async (customerEmail, payment) => {\n const { cartId } = get()\n if (!cartId) throw new Error('No active cart')\n\n set({ cartLoading: true })\n try {\n const order = await client.checkout(cartId, customerEmail, payment)\n set({\n cartId: null,\n items: [],\n itemCount: 0,\n subtotal: 0,\n taxAmount: 0,\n total: 0,\n taxBreakdown: [],\n productImages: {},\n cartOpen: false,\n })\n return order\n } finally {\n set({ cartLoading: false })\n }\n },\n }),\n\n // ── Persist config ─────────────────────────────────────────────────\n {\n name: `${storagePrefix}-cart`,\n partialize: (state) => ({\n cartId: state.cartId,\n productImages: state.productImages,\n }),\n }\n )\n )\n}\n\nfunction applyCart(\n set: (partial: Partial<CartState>) => void,\n get: () => CartState,\n cart: Cart\n) {\n const productImages = get().productImages\n const items = (cart.items ?? []).map((item) => ({\n ...item,\n image_url: item.image_url || productImages[item.product_id] || null,\n }))\n set({\n cartId: cart.id,\n items,\n itemCount: cart.item_count ?? 0,\n subtotal: cart.subtotal ?? 0,\n taxAmount: cart.tax_amount ?? 0,\n total: cart.total ?? 0,\n taxBreakdown: cart.tax_breakdown ?? [],\n })\n}\n","import { createStore } from 'zustand/vanilla'\nimport { persist } from 'zustand/middleware'\nimport type { WhaleClient } from '../../client.js'\nimport type { Customer } from '../../types.js'\n\nexport interface AuthState {\n customer: Customer | null\n sessionToken: string | null\n sessionExpiresAt: string | null\n authLoading: boolean\n}\n\nexport interface AuthActions {\n sendOTP: (email: string) => Promise<boolean>\n verifyOTP: (email: string, code: string) => Promise<boolean>\n restoreSession: () => Promise<void>\n isSessionValid: () => boolean\n logout: () => void\n fetchCustomer: (id: string) => Promise<void>\n}\n\nexport type AuthStore = ReturnType<typeof createAuthStore>\n\nexport function createAuthStore(client: WhaleClient, storagePrefix: string) {\n return createStore<AuthState & AuthActions>()(\n persist(\n (set, get) => ({\n // ── Initial state ────────────────────────────────────────────────\n customer: null,\n sessionToken: null,\n sessionExpiresAt: null,\n authLoading: false,\n\n // ── Actions ──────────────────────────────────────────────────────\n sendOTP: async (email) => {\n set({ authLoading: true })\n try {\n const res = await client.sendCode(email)\n return res.sent\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Could not send code'\n throw new Error(message)\n } finally {\n set({ authLoading: false })\n }\n },\n\n verifyOTP: async (email, code) => {\n set({ authLoading: true })\n try {\n const res = await client.verifyCode(email, code)\n client.setSessionToken(res.token_hash)\n set({\n sessionToken: res.token_hash,\n sessionExpiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),\n })\n\n if (res.customer?.id) {\n try {\n const full = await client.getCustomer(res.customer.id)\n set({ customer: full })\n } catch {\n set({ customer: res.customer })\n }\n }\n\n return res.needs_profile ?? false\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Verification failed'\n throw new Error(message)\n } finally {\n set({ authLoading: false })\n }\n },\n\n restoreSession: async () => {\n const { sessionToken, sessionExpiresAt, customer } = get()\n if (!sessionToken || !sessionExpiresAt) return\n\n if (new Date(sessionExpiresAt) <= new Date()) {\n client.setSessionToken(null)\n set({ sessionToken: null, sessionExpiresAt: null, customer: null })\n return\n }\n\n client.setSessionToken(sessionToken)\n\n if (customer?.id) {\n try {\n const fresh = await client.getCustomer(customer.id)\n set({ customer: fresh })\n } catch {\n client.setSessionToken(null)\n set({ sessionToken: null, sessionExpiresAt: null, customer: null })\n }\n }\n },\n\n isSessionValid: () => {\n const { sessionToken, sessionExpiresAt } = get()\n if (!sessionToken || !sessionExpiresAt) return false\n return new Date(sessionExpiresAt) > new Date()\n },\n\n logout: () => {\n client.setSessionToken(null)\n set({ customer: null, sessionToken: null, sessionExpiresAt: null })\n },\n\n fetchCustomer: async (id) => {\n try {\n const customer = await client.getCustomer(id)\n set({ customer })\n } catch (err) {\n console.error('[whale-storefront] fetchCustomer failed:', err)\n }\n },\n }),\n\n // ── Persist config ─────────────────────────────────────────────────\n {\n name: `${storagePrefix}-auth`,\n partialize: (state) => ({\n sessionToken: state.sessionToken,\n sessionExpiresAt: state.sessionExpiresAt,\n customer: state.customer\n ? {\n id: state.customer.id,\n email: state.customer.email,\n first_name: state.customer.first_name,\n last_name: state.customer.last_name,\n phone: state.customer.phone,\n loyalty_points: state.customer.loyalty_points,\n loyalty_tier: state.customer.loyalty_tier,\n total_spent: state.customer.total_spent,\n total_orders: state.customer.total_orders,\n }\n : null,\n }),\n }\n )\n )\n}\n","'use client'\n\nimport { useContext, useRef, useCallback } from 'react'\nimport { WhaleContext } from '../context.js'\nimport type { EventType } from '../../types.js'\n\nconst SESSION_KEY_SUFFIX = '-analytics-session'\n\ninterface SessionData {\n id: string\n createdAt: number\n}\n\nexport function useAnalytics() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useAnalytics must be used within <WhaleProvider>')\n\n const { client, config } = ctx\n const sessionPromiseRef = useRef<Promise<string> | null>(null)\n const sessionKey = `${config.storagePrefix}${SESSION_KEY_SUFFIX}`\n\n const getOrCreateSession = useCallback(async (): Promise<string> => {\n if (sessionPromiseRef.current) return sessionPromiseRef.current\n\n sessionPromiseRef.current = (async () => {\n // Check stored session\n try {\n const raw = localStorage.getItem(sessionKey)\n if (raw) {\n const stored: SessionData = JSON.parse(raw)\n if (Date.now() - stored.createdAt < config.sessionTtl) {\n // Refresh last_active silently\n client.updateSession(stored.id, { last_active_at: new Date().toISOString() }).catch(() => {})\n return stored.id\n }\n }\n } catch {\n // ignore\n }\n\n // Create new\n try {\n const session = await client.createSession({\n user_agent: navigator.userAgent,\n referrer: document.referrer || undefined,\n })\n if (session?.id) {\n localStorage.setItem(sessionKey, JSON.stringify({ id: session.id, createdAt: Date.now() }))\n return session.id\n }\n } catch {\n // ignore\n }\n\n // Fallback local ID\n const fallbackId = `local-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\n localStorage.setItem(sessionKey, JSON.stringify({ id: fallbackId, createdAt: Date.now() }))\n return fallbackId\n })()\n\n sessionPromiseRef.current.finally(() => {\n sessionPromiseRef.current = null\n })\n\n return sessionPromiseRef.current\n }, [client, config.sessionTtl, sessionKey])\n\n const track = useCallback(\n async (eventType: EventType, data: Record<string, unknown> = {}) => {\n try {\n const sessionId = await getOrCreateSession()\n await client.trackEvent({ session_id: sessionId, event_type: eventType, event_data: data })\n } catch {\n // fire-and-forget\n }\n },\n [client, getOrCreateSession]\n )\n\n const linkCustomer = useCallback(\n async (customerId: string) => {\n try {\n const sessionId = await getOrCreateSession()\n if (sessionId.startsWith('local-')) return\n await client.updateSession(sessionId, { customer_id: customerId })\n } catch {\n // ignore\n }\n },\n [client, getOrCreateSession]\n )\n\n const trackPageView = useCallback(\n (url: string, referrer?: string) => {\n track('page_view', { url, referrer })\n },\n [track]\n )\n\n const trackProductView = useCallback(\n (productId: string, productName: string, category: string, price?: number) => {\n track('product_view', { product_id: productId, product_name: productName, category, price })\n },\n [track]\n )\n\n const trackCategoryView = useCallback(\n (categoryId: string, categoryName: string) => {\n track('category_view', { category_id: categoryId, category_name: categoryName })\n },\n [track]\n )\n\n const trackSearch = useCallback(\n (query: string, resultCount?: number) => {\n track('search', { query, result_count: resultCount })\n },\n [track]\n )\n\n const trackBeginCheckout = useCallback(\n (cartId: string, total: number, itemCount: number) => {\n track('begin_checkout', { cart_id: cartId, total, item_count: itemCount })\n },\n [track]\n )\n\n const trackPurchase = useCallback(\n (orderId: string, orderNumber: string, total: number) => {\n track('purchase', { order_id: orderId, order_number: orderNumber, total })\n },\n [track]\n )\n\n const trackAddToCart = useCallback(\n (productId: string, productName: string, quantity: number, price: number, tier?: string) => {\n track('add_to_cart', { product_id: productId, product_name: productName, quantity, price, tier })\n },\n [track]\n )\n\n const trackRemoveFromCart = useCallback(\n (productId: string, productName: string) => {\n track('remove_from_cart', { product_id: productId, product_name: productName })\n },\n [track]\n )\n\n return {\n track,\n trackPageView,\n trackProductView,\n trackCategoryView,\n trackSearch,\n trackBeginCheckout,\n trackPurchase,\n trackAddToCart,\n trackRemoveFromCart,\n linkCustomer,\n getOrCreateSession,\n }\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { useStore } from 'zustand'\nimport { useShallow } from 'zustand/react/shallow'\nimport { WhaleContext } from '../context.js'\n\nexport function useAuth() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useAuth must be used within <WhaleProvider>')\n\n return useStore(ctx.authStore, useShallow((s) => ({\n customer: s.customer,\n authLoading: s.authLoading,\n sessionToken: s.sessionToken,\n isAuthenticated: s.isSessionValid(),\n sendCode: s.sendOTP,\n verifyCode: s.verifyOTP,\n restoreSession: s.restoreSession,\n logout: s.logout,\n fetchCustomer: s.fetchCustomer,\n })))\n}\n","'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { useAnalytics } from '../hooks/use-analytics.js'\nimport { useAuth } from '../hooks/use-auth.js'\n\n/**\n * Auto-tracks page views on pathname change and links customer sessions.\n * Rendered internally by WhaleProvider — storefronts don't need to add this manually.\n */\nexport function AnalyticsTracker({ pathname }: { pathname: string }) {\n const { trackPageView, linkCustomer } = useAnalytics()\n const { customer } = useAuth()\n const prevPathname = useRef<string | null>(null)\n const linkedCustomerId = useRef<string | null>(null)\n\n // Track page views on route change\n useEffect(() => {\n if (pathname === prevPathname.current) return\n const referrer = prevPathname.current || (typeof document !== 'undefined' ? document.referrer : '')\n prevPathname.current = pathname\n trackPageView(pathname, referrer || undefined)\n }, [pathname, trackPageView])\n\n // Link customer session on login\n useEffect(() => {\n if (customer?.id && customer.id !== linkedCustomerId.current) {\n linkedCustomerId.current = customer.id\n linkCustomer(customer.id)\n }\n }, [customer?.id, linkCustomer])\n\n return null\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { useStore } from 'zustand'\nimport { useShallow } from 'zustand/react/shallow'\nimport { WhaleContext } from '../context.js'\nimport type { CartState, CartActions } from '../stores/cart-store.js'\n\ntype CartReturn = Pick<\n CartState & CartActions,\n 'cartId' | 'cartOpen' | 'cartLoading' | 'items' | 'itemCount' | 'subtotal' | 'taxAmount' | 'total' | 'taxBreakdown' | 'productImages' |\n 'addItem' | 'removeItem' | 'updateQuantity' | 'toggleCart' | 'openCart' | 'closeCart' | 'checkout' | 'initCart' | 'syncCart' | 'clearCart'\n>\n\nexport function useCart() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCart must be used within <WhaleProvider>')\n\n return useStore(ctx.cartStore, useShallow((s) => ({\n cartId: s.cartId,\n items: s.items,\n itemCount: s.itemCount,\n subtotal: s.subtotal,\n taxAmount: s.taxAmount,\n total: s.total,\n taxBreakdown: s.taxBreakdown,\n cartOpen: s.cartOpen,\n cartLoading: s.cartLoading,\n productImages: s.productImages,\n addItem: s.addItem,\n removeItem: s.removeItem,\n updateQuantity: s.updateQuantity,\n toggleCart: s.toggleCart,\n openCart: s.openCart,\n closeCart: s.closeCart,\n initCart: s.initCart,\n syncCart: s.syncCart,\n clearCart: s.clearCart,\n checkout: s.checkout,\n })))\n}\n\n/** Granular selector — only re-renders on count change */\nexport function useCartItemCount(): number {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCartItemCount must be used within <WhaleProvider>')\n return useStore(ctx.cartStore, (s) => s.itemCount)\n}\n\n/** Granular selector — only re-renders on total change */\nexport function useCartTotal(): number {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCartTotal must be used within <WhaleProvider>')\n return useStore(ctx.cartStore, (s) => s.total)\n}\n","'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { useCart } from '../hooks/use-cart.js'\n\n/**\n * Hydrates cart from gateway on mount if a cartId is persisted.\n * Rendered internally by WhaleProvider.\n */\nexport function CartInitializer() {\n const { cartId, syncCart } = useCart()\n const initialized = useRef(false)\n\n useEffect(() => {\n if (initialized.current) return\n initialized.current = true\n if (cartId) {\n syncCart().catch(() => {\n // Cart may have expired — that's fine, addItem will auto-recover\n })\n }\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n return null\n}\n","'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { useAuth } from '../hooks/use-auth.js'\n\n/**\n * Restores auth session on mount — syncs persisted token to client.\n * Rendered internally by WhaleProvider.\n */\nexport function AuthInitializer() {\n const { restoreSession } = useAuth()\n const restored = useRef(false)\n\n useEffect(() => {\n if (restored.current) return\n restored.current = true\n restoreSession()\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n return null\n}\n","'use client'\n\nimport { useMemo, type ReactNode } from 'react'\nimport { usePathname } from 'next/navigation'\nimport { WhaleClient } from '../client.js'\nimport type { WhaleStorefrontConfig, Product } from '../types.js'\nimport { WhaleContext, type WhaleContextValue } from './context.js'\nimport { createCartStore } from './stores/cart-store.js'\nimport { createAuthStore } from './stores/auth-store.js'\nimport { AnalyticsTracker } from './components/analytics-tracker.js'\nimport { CartInitializer } from './components/cart-initializer.js'\nimport { AuthInitializer } from './components/auth-initializer.js'\n\nexport interface WhaleProviderProps extends WhaleStorefrontConfig {\n children: ReactNode\n /** Server-fetched products passed to client for hooks */\n products?: Product[]\n}\n\nexport function WhaleProvider({\n children,\n products = [],\n storeId,\n apiKey,\n gatewayUrl,\n proxyPath,\n mediaSigningSecret,\n supabaseHost,\n storagePrefix,\n sessionTtl,\n debug,\n}: WhaleProviderProps) {\n const pathname = usePathname()\n\n const ctx = useMemo<WhaleContextValue>(() => {\n const resolvedConfig = {\n storeId,\n apiKey,\n gatewayUrl: gatewayUrl || 'https://whale-gateway.fly.dev',\n proxyPath: proxyPath || '/api/gw',\n mediaSigningSecret: mediaSigningSecret || '',\n supabaseHost: supabaseHost || '',\n storagePrefix: storagePrefix || 'whale',\n sessionTtl: sessionTtl || 30 * 60 * 1000,\n debug: debug || false,\n }\n\n const client = new WhaleClient({\n storeId,\n apiKey,\n gatewayUrl: resolvedConfig.gatewayUrl,\n proxyPath: resolvedConfig.proxyPath,\n })\n\n // Analytics callbacks wired into cart store\n // These get called by the cart store on add/remove and fire analytics events.\n // We can't use the useAnalytics hook here (not in a component), so we use\n // the client directly — the AnalyticsTracker manages sessions.\n const cartStore = createCartStore(client, resolvedConfig.storagePrefix)\n const authStore = createAuthStore(client, resolvedConfig.storagePrefix)\n\n return {\n client,\n config: resolvedConfig,\n cartStore,\n authStore,\n products,\n }\n // Only recreate when identity changes — storeId + apiKey\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [storeId, apiKey])\n\n // Update products on the context when they change (e.g. re-fetched)\n const value = useMemo<WhaleContextValue>(\n () => ({ ...ctx, products }),\n [ctx, products]\n )\n\n return (\n <WhaleContext.Provider value={value}>\n <AuthInitializer />\n <CartInitializer />\n <AnalyticsTracker pathname={pathname} />\n {children}\n </WhaleContext.Provider>\n )\n}\n","'use client'\n\nimport { useContext, useState, useEffect, useMemo } from 'react'\nimport { WhaleContext } from '../context.js'\nimport type { Product } from '../../types.js'\n\n/**\n * Returns products passed via WhaleProvider.\n * Optionally filters by category or search.\n */\nexport function useProducts(opts?: {\n categoryId?: string\n search?: string\n}) {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useProducts must be used within <WhaleProvider>')\n\n const allProducts = ctx.products\n\n const products = useMemo(() => {\n let result = allProducts\n if (opts?.categoryId) {\n result = result.filter((p) => p.primary_category_id === opts.categoryId)\n }\n if (opts?.search) {\n const q = opts.search.toLowerCase()\n result = result.filter(\n (p) =>\n p.name.toLowerCase().includes(q) ||\n p.description?.toLowerCase().includes(q) ||\n p.slug.toLowerCase().includes(q)\n )\n }\n return result\n }, [allProducts, opts?.categoryId, opts?.search])\n\n return {\n products,\n allProducts,\n loading: false,\n }\n}\n\n/**\n * Returns a single product by slug from the provider's product list.\n */\nexport function useProduct(slug: string | null | undefined) {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useProduct must be used within <WhaleProvider>')\n\n const product = useMemo(() => {\n if (!slug) return null\n return ctx.products.find((p) => p.slug === slug) ?? null\n }, [ctx.products, slug])\n\n return {\n product,\n loading: false,\n }\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { WhaleContext } from '../context.js'\nimport type { WhaleClient } from '../../client.js'\n\nexport function useWhaleClient(): WhaleClient {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useWhaleClient must be used within <WhaleProvider>')\n return ctx.client\n}\n","'use client'\n\nimport { useContext, useState, useEffect, useCallback } from 'react'\nimport { useStore } from 'zustand'\nimport { WhaleContext } from '../context.js'\nimport type { Order, CustomerAnalytics } from '../../types.js'\n\nexport function useCustomerOrders() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCustomerOrders must be used within <WhaleProvider>')\n\n const customer = useStore(ctx.authStore, (s) => s.customer)\n const [orders, setOrders] = useState<Order[]>([])\n const [loading, setLoading] = useState(false)\n\n const refresh = useCallback(async () => {\n if (!customer?.id) {\n setOrders([])\n return\n }\n setLoading(true)\n try {\n const data = await ctx.client.getCustomerOrders(customer.id)\n setOrders(data)\n } catch {\n setOrders([])\n } finally {\n setLoading(false)\n }\n }, [customer?.id, ctx.client])\n\n useEffect(() => {\n refresh()\n }, [refresh])\n\n return { orders, loading, refresh }\n}\n\nexport function useCustomerAnalytics() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCustomerAnalytics must be used within <WhaleProvider>')\n\n const customer = useStore(ctx.authStore, (s) => s.customer)\n const [analytics, setAnalytics] = useState<CustomerAnalytics | null>(null)\n const [loading, setLoading] = useState(false)\n\n useEffect(() => {\n if (!customer?.id) {\n setAnalytics(null)\n return\n }\n setLoading(true)\n const name = `${customer.first_name} ${customer.last_name}`.trim()\n ctx.client\n .getCustomerAnalytics(customer.id, name || undefined)\n .then(setAnalytics)\n .catch(() => setAnalytics(null))\n .finally(() => setLoading(false))\n }, [customer?.id, customer?.first_name, customer?.last_name, ctx.client])\n\n return { analytics, loading }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/react/context.ts","../../src/react/stores/cart-store.ts","../../src/react/stores/auth-store.ts","../../src/react/hooks/use-analytics.ts","../../src/react/hooks/use-auth.ts","../../src/react/components/analytics-tracker.tsx","../../src/react/hooks/use-cart.ts","../../src/react/components/cart-initializer.tsx","../../src/react/components/auth-initializer.tsx","../../src/react/components/pixel-initializer.tsx","../../src/react/provider.tsx","../../src/react/hooks/use-products.ts","../../src/react/hooks/use-client.ts","../../src/react/hooks/use-customer.ts"],"names":["createStore","persist","useContext","useRef","useStore","useShallow","useEffect","useCallback","useMemo","useState"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext } from 'react'\nimport type { WhaleClient } from '../client.js'\nimport type { Product } from '../types.js'\nimport type { CartStore } from './stores/cart-store.js'\nimport type { AuthStore } from './stores/auth-store.js'\nimport type { PixelManager } from '../pixels/pixel-manager.js'\n\nexport interface WhaleContextValue {\n client: WhaleClient\n config: {\n storeId: string\n apiKey: string\n gatewayUrl: string\n proxyPath: string\n mediaSigningSecret: string\n supabaseHost: string\n storagePrefix: string\n sessionTtl: number\n debug: boolean\n trackingEnabled: boolean\n recordingRate: number\n }\n cartStore: CartStore\n authStore: AuthStore\n /** Products fetched server-side and passed via provider */\n products: Product[]\n /** Pixel manager — set after storefront config loads */\n pixelManager: PixelManager | null\n}\n\nexport const WhaleContext = createContext<WhaleContextValue | null>(null)\n","import { createStore } from 'zustand/vanilla'\nimport { persist } from 'zustand/middleware'\nimport type { WhaleClient } from '../../client.js'\nimport type { Cart, CartItem, TaxBreakdown, PaymentData, Order } from '../../types.js'\n\nexport interface CartState {\n cartId: string | null\n items: CartItem[]\n itemCount: number\n subtotal: number\n taxAmount: number\n total: number\n taxBreakdown: TaxBreakdown[]\n cartOpen: boolean\n cartLoading: boolean\n productImages: Record<string, string>\n addItemInFlight: boolean\n}\n\nexport interface CartActions {\n openCart: () => void\n closeCart: () => void\n toggleCart: () => void\n initCart: () => Promise<void>\n syncCart: () => Promise<void>\n addItem: (\n productId: string,\n quantity: number,\n tier?: string,\n unitPrice?: number,\n imageUrl?: string | null,\n productName?: string\n ) => Promise<void>\n updateQuantity: (itemId: string, quantity: number) => Promise<void>\n removeItem: (itemId: string, productName?: string) => Promise<void>\n clearCart: () => void\n checkout: (customerEmail?: string, payment?: PaymentData) => Promise<Order>\n}\n\nexport type CartStore = ReturnType<typeof createCartStore>\n\nexport function createCartStore(\n client: WhaleClient,\n storagePrefix: string,\n onAddToCart?: (productId: string, productName: string, quantity: number, price: number, tier?: string) => void,\n onRemoveFromCart?: (productId: string, productName: string) => void\n) {\n return createStore<CartState & CartActions>()(\n persist(\n (set, get) => ({\n // ── Initial state ────────────────────────────────────────────────\n cartId: null,\n items: [],\n itemCount: 0,\n subtotal: 0,\n taxAmount: 0,\n total: 0,\n taxBreakdown: [],\n cartOpen: false,\n cartLoading: false,\n productImages: {},\n addItemInFlight: false,\n\n // ── Cart UI ──────────────────────────────────────────────────────\n openCart: () => set({ cartOpen: true }),\n closeCart: () => set({ cartOpen: false }),\n toggleCart: () => set((s) => ({ cartOpen: !s.cartOpen })),\n\n // ── Cart data ────────────────────────────────────────────────────\n initCart: async () => {\n const { cartId, syncCart } = get()\n\n if (cartId) {\n try {\n await syncCart()\n } catch {\n const cart = await client.createCart()\n applyCart(set, get, cart)\n }\n return\n }\n\n try {\n const cart = await client.createCart()\n applyCart(set, get, cart)\n } catch (err) {\n console.error('[whale-storefront] initCart failed:', err)\n }\n },\n\n syncCart: async () => {\n const { cartId, productImages } = get()\n if (!cartId) return\n\n try {\n const cart = await client.getCart(cartId)\n const items = (cart.items ?? []).map((item) => ({\n ...item,\n image_url: item.image_url || productImages[item.product_id] || null,\n }))\n set({\n items,\n itemCount: cart.item_count ?? 0,\n subtotal: cart.subtotal ?? 0,\n taxAmount: cart.tax_amount ?? 0,\n total: cart.total ?? 0,\n taxBreakdown: cart.tax_breakdown ?? [],\n })\n } catch (err) {\n console.error('[whale-storefront] syncCart failed:', err)\n throw err\n }\n },\n\n addItem: async (productId, quantity, tier, unitPrice, imageUrl, productName) => {\n // Race-condition guard: prevent double-click\n if (get().addItemInFlight) return\n set({ cartLoading: true, addItemInFlight: true })\n\n try {\n let { cartId } = get()\n\n if (!cartId) {\n await get().initCart()\n cartId = get().cartId\n }\n\n if (!cartId) throw new Error('Could not initialise cart')\n\n if (imageUrl) {\n set((s) => ({ productImages: { ...s.productImages, [productId]: imageUrl } }))\n }\n\n try {\n await client.addToCart(cartId, productId, quantity, { tier, unitPrice })\n } catch (err: unknown) {\n // Cart expired (404/410) — auto-recover\n const status = (err as { status?: number }).status\n if (status === 404 || status === 410) {\n const newCart = await client.createCart()\n set({ cartId: newCart.id })\n await client.addToCart(newCart.id, productId, quantity, { tier, unitPrice })\n } else {\n throw err\n }\n }\n\n await get().syncCart()\n\n // Analytics callback\n onAddToCart?.(productId, productName || '', quantity, unitPrice || 0, tier)\n } finally {\n set({ cartLoading: false, addItemInFlight: false })\n }\n },\n\n updateQuantity: async (itemId, quantity) => {\n set({ cartLoading: true })\n try {\n const { cartId } = get()\n if (!cartId) return\n await client.updateCartItem(cartId, itemId, quantity)\n await get().syncCart()\n } finally {\n set({ cartLoading: false })\n }\n },\n\n removeItem: async (itemId, productName) => {\n set({ cartLoading: true })\n try {\n const { cartId, items } = get()\n if (!cartId) return\n\n const item = items.find((i) => i.id === itemId)\n await client.removeCartItem(cartId, itemId)\n await get().syncCart()\n\n if (item) {\n onRemoveFromCart?.(item.product_id, productName || item.product_name)\n }\n } finally {\n set({ cartLoading: false })\n }\n },\n\n clearCart: () => {\n set({\n cartId: null,\n items: [],\n itemCount: 0,\n subtotal: 0,\n taxAmount: 0,\n total: 0,\n taxBreakdown: [],\n productImages: {},\n })\n },\n\n checkout: async (customerEmail, payment) => {\n const { cartId } = get()\n if (!cartId) throw new Error('No active cart')\n\n set({ cartLoading: true })\n try {\n const order = await client.checkout(cartId, customerEmail, payment)\n set({\n cartId: null,\n items: [],\n itemCount: 0,\n subtotal: 0,\n taxAmount: 0,\n total: 0,\n taxBreakdown: [],\n productImages: {},\n cartOpen: false,\n })\n return order\n } finally {\n set({ cartLoading: false })\n }\n },\n }),\n\n // ── Persist config ─────────────────────────────────────────────────\n {\n name: `${storagePrefix}-cart`,\n partialize: (state) => ({\n cartId: state.cartId,\n productImages: state.productImages,\n }),\n }\n )\n )\n}\n\nfunction applyCart(\n set: (partial: Partial<CartState>) => void,\n get: () => CartState,\n cart: Cart\n) {\n const productImages = get().productImages\n const items = (cart.items ?? []).map((item) => ({\n ...item,\n image_url: item.image_url || productImages[item.product_id] || null,\n }))\n set({\n cartId: cart.id,\n items,\n itemCount: cart.item_count ?? 0,\n subtotal: cart.subtotal ?? 0,\n taxAmount: cart.tax_amount ?? 0,\n total: cart.total ?? 0,\n taxBreakdown: cart.tax_breakdown ?? [],\n })\n}\n","import { createStore } from 'zustand/vanilla'\nimport { persist } from 'zustand/middleware'\nimport type { WhaleClient } from '../../client.js'\nimport type { Customer } from '../../types.js'\n\nexport interface AuthState {\n customer: Customer | null\n sessionToken: string | null\n sessionExpiresAt: string | null\n authLoading: boolean\n}\n\nexport interface AuthActions {\n sendOTP: (email: string) => Promise<boolean>\n verifyOTP: (email: string, code: string) => Promise<boolean>\n restoreSession: () => Promise<void>\n isSessionValid: () => boolean\n logout: () => void\n fetchCustomer: (id: string) => Promise<void>\n}\n\nexport type AuthStore = ReturnType<typeof createAuthStore>\n\nexport function createAuthStore(client: WhaleClient, storagePrefix: string) {\n return createStore<AuthState & AuthActions>()(\n persist(\n (set, get) => ({\n // ── Initial state ────────────────────────────────────────────────\n customer: null,\n sessionToken: null,\n sessionExpiresAt: null,\n authLoading: false,\n\n // ── Actions ──────────────────────────────────────────────────────\n sendOTP: async (email) => {\n set({ authLoading: true })\n try {\n const res = await client.sendCode(email)\n return res.sent\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Could not send code'\n throw new Error(message)\n } finally {\n set({ authLoading: false })\n }\n },\n\n verifyOTP: async (email, code) => {\n set({ authLoading: true })\n try {\n const res = await client.verifyCode(email, code)\n client.setSessionToken(res.token_hash)\n set({\n sessionToken: res.token_hash,\n sessionExpiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),\n })\n\n if (res.customer?.id) {\n try {\n const full = await client.getCustomer(res.customer.id)\n set({ customer: full })\n } catch {\n set({ customer: res.customer })\n }\n }\n\n return res.needs_profile ?? false\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Verification failed'\n throw new Error(message)\n } finally {\n set({ authLoading: false })\n }\n },\n\n restoreSession: async () => {\n const { sessionToken, sessionExpiresAt, customer } = get()\n if (!sessionToken || !sessionExpiresAt) return\n\n if (new Date(sessionExpiresAt) <= new Date()) {\n client.setSessionToken(null)\n set({ sessionToken: null, sessionExpiresAt: null, customer: null })\n return\n }\n\n client.setSessionToken(sessionToken)\n\n if (customer?.id) {\n try {\n const fresh = await client.getCustomer(customer.id)\n set({ customer: fresh })\n } catch {\n client.setSessionToken(null)\n set({ sessionToken: null, sessionExpiresAt: null, customer: null })\n }\n }\n },\n\n isSessionValid: () => {\n const { sessionToken, sessionExpiresAt } = get()\n if (!sessionToken || !sessionExpiresAt) return false\n return new Date(sessionExpiresAt) > new Date()\n },\n\n logout: () => {\n client.setSessionToken(null)\n set({ customer: null, sessionToken: null, sessionExpiresAt: null })\n },\n\n fetchCustomer: async (id) => {\n try {\n const customer = await client.getCustomer(id)\n set({ customer })\n } catch (err) {\n console.error('[whale-storefront] fetchCustomer failed:', err)\n }\n },\n }),\n\n // ── Persist config ─────────────────────────────────────────────────\n {\n name: `${storagePrefix}-auth`,\n partialize: (state) => ({\n sessionToken: state.sessionToken,\n sessionExpiresAt: state.sessionExpiresAt,\n customer: state.customer\n ? {\n id: state.customer.id,\n email: state.customer.email,\n first_name: state.customer.first_name,\n last_name: state.customer.last_name,\n phone: state.customer.phone,\n loyalty_points: state.customer.loyalty_points,\n loyalty_tier: state.customer.loyalty_tier,\n total_spent: state.customer.total_spent,\n total_orders: state.customer.total_orders,\n }\n : null,\n }),\n }\n )\n )\n}\n","'use client'\n\nimport { useContext, useRef, useCallback } from 'react'\nimport { WhaleContext } from '../context.js'\nimport type { EventType } from '../../types.js'\n\nconst SESSION_KEY_SUFFIX = '-analytics-session'\n\ninterface SessionData {\n id: string\n createdAt: number\n}\n\nexport function useAnalytics() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useAnalytics must be used within <WhaleProvider>')\n\n const { client, config, pixelManager } = ctx\n const sessionPromiseRef = useRef<Promise<string> | null>(null)\n const sessionKey = `${config.storagePrefix}${SESSION_KEY_SUFFIX}`\n\n const getOrCreateSession = useCallback(async (): Promise<string> => {\n if (sessionPromiseRef.current) return sessionPromiseRef.current\n\n sessionPromiseRef.current = (async () => {\n // Check stored session\n try {\n const raw = localStorage.getItem(sessionKey)\n if (raw) {\n const stored: SessionData = JSON.parse(raw)\n if (Date.now() - stored.createdAt < config.sessionTtl) {\n // Refresh last_active silently\n client.updateSession(stored.id, { last_active_at: new Date().toISOString() }).catch(() => {})\n return stored.id\n }\n }\n } catch {\n // ignore\n }\n\n // Create new\n try {\n const session = await client.createSession({\n user_agent: navigator.userAgent,\n referrer: document.referrer || undefined,\n })\n if (session?.id) {\n localStorage.setItem(sessionKey, JSON.stringify({ id: session.id, createdAt: Date.now() }))\n return session.id\n }\n } catch {\n // ignore\n }\n\n // Fallback local ID\n const fallbackId = `local-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\n localStorage.setItem(sessionKey, JSON.stringify({ id: fallbackId, createdAt: Date.now() }))\n return fallbackId\n })()\n\n sessionPromiseRef.current.finally(() => {\n sessionPromiseRef.current = null\n })\n\n return sessionPromiseRef.current\n }, [client, config.sessionTtl, sessionKey])\n\n const trackingEnabled = config.trackingEnabled\n\n const track = useCallback(\n async (eventType: EventType, data: Record<string, unknown> = {}) => {\n if (!trackingEnabled) return\n\n // Fire pixel events instantly (client-side)\n pixelManager?.track(eventType, data)\n\n // Then fire gateway event (server-side attribution)\n try {\n const sessionId = await getOrCreateSession()\n await client.trackEvent({ session_id: sessionId, event_type: eventType, event_data: data })\n } catch {\n // fire-and-forget\n }\n },\n [client, getOrCreateSession, pixelManager, trackingEnabled]\n )\n\n const linkCustomer = useCallback(\n async (customerId: string) => {\n if (!trackingEnabled) return\n try {\n const sessionId = await getOrCreateSession()\n if (sessionId.startsWith('local-')) return\n await client.updateSession(sessionId, { customer_id: customerId })\n } catch {\n // ignore\n }\n },\n [client, getOrCreateSession, trackingEnabled]\n )\n\n const trackPageView = useCallback(\n (url: string, referrer?: string) => {\n track('page_view', { url, referrer })\n },\n [track]\n )\n\n const trackProductView = useCallback(\n (productId: string, productName: string, category: string, price?: number) => {\n track('product_view', { product_id: productId, product_name: productName, category, price })\n },\n [track]\n )\n\n const trackCategoryView = useCallback(\n (categoryId: string, categoryName: string) => {\n track('category_view', { category_id: categoryId, category_name: categoryName })\n },\n [track]\n )\n\n const trackSearch = useCallback(\n (query: string, resultCount?: number) => {\n track('search', { query, result_count: resultCount })\n },\n [track]\n )\n\n const trackBeginCheckout = useCallback(\n (cartId: string, total: number, itemCount: number) => {\n track('begin_checkout', { cart_id: cartId, total, item_count: itemCount })\n },\n [track]\n )\n\n const trackPurchase = useCallback(\n (orderId: string, orderNumber: string, total: number) => {\n track('purchase', { order_id: orderId, order_number: orderNumber, total })\n },\n [track]\n )\n\n const trackAddToCart = useCallback(\n (productId: string, productName: string, quantity: number, price: number, tier?: string) => {\n track('add_to_cart', { product_id: productId, product_name: productName, quantity, price, tier })\n },\n [track]\n )\n\n const trackRemoveFromCart = useCallback(\n (productId: string, productName: string) => {\n track('remove_from_cart', { product_id: productId, product_name: productName })\n },\n [track]\n )\n\n return {\n track,\n trackPageView,\n trackProductView,\n trackCategoryView,\n trackSearch,\n trackBeginCheckout,\n trackPurchase,\n trackAddToCart,\n trackRemoveFromCart,\n linkCustomer,\n getOrCreateSession,\n /** Whether tracking is globally enabled for this storefront */\n trackingEnabled,\n /** Configured recording sample rate (0–1) for behavioral session replays */\n recordingRate: config.recordingRate,\n }\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { useStore } from 'zustand'\nimport { useShallow } from 'zustand/react/shallow'\nimport { WhaleContext } from '../context.js'\n\nexport function useAuth() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useAuth must be used within <WhaleProvider>')\n\n return useStore(ctx.authStore, useShallow((s) => ({\n customer: s.customer,\n authLoading: s.authLoading,\n sessionToken: s.sessionToken,\n isAuthenticated: s.isSessionValid(),\n sendCode: s.sendOTP,\n verifyCode: s.verifyOTP,\n restoreSession: s.restoreSession,\n logout: s.logout,\n fetchCustomer: s.fetchCustomer,\n })))\n}\n","'use client'\n\nimport { useEffect, useRef, useContext } from 'react'\nimport { WhaleContext } from '../context.js'\nimport { useAnalytics } from '../hooks/use-analytics.js'\nimport { useAuth } from '../hooks/use-auth.js'\n\n/**\n * Auto-tracks page views on pathname change and links customer sessions.\n * Rendered internally by WhaleProvider — storefronts don't need to add this manually.\n *\n * When `config.trackingEnabled` is false the component renders nothing and\n * skips all side-effects — the underlying hook guards individual calls too,\n * but short-circuiting here avoids session creation entirely.\n */\nexport function AnalyticsTracker({ pathname }: { pathname: string }) {\n const ctx = useContext(WhaleContext)\n const { trackPageView, linkCustomer } = useAnalytics()\n const { customer } = useAuth()\n const prevPathname = useRef<string | null>(null)\n const linkedCustomerId = useRef<string | null>(null)\n\n const trackingEnabled = ctx?.config.trackingEnabled ?? true\n\n // Track page views on route change\n useEffect(() => {\n if (!trackingEnabled) return\n if (pathname === prevPathname.current) return\n const referrer = prevPathname.current || (typeof document !== 'undefined' ? document.referrer : '')\n prevPathname.current = pathname\n trackPageView(pathname, referrer || undefined)\n }, [pathname, trackPageView, trackingEnabled])\n\n // Link customer session on login\n useEffect(() => {\n if (!trackingEnabled) return\n if (customer?.id && customer.id !== linkedCustomerId.current) {\n linkedCustomerId.current = customer.id\n linkCustomer(customer.id)\n }\n }, [customer?.id, linkCustomer, trackingEnabled])\n\n return null\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { useStore } from 'zustand'\nimport { useShallow } from 'zustand/react/shallow'\nimport { WhaleContext } from '../context.js'\nimport type { CartState, CartActions } from '../stores/cart-store.js'\n\ntype CartReturn = Pick<\n CartState & CartActions,\n 'cartId' | 'cartOpen' | 'cartLoading' | 'items' | 'itemCount' | 'subtotal' | 'taxAmount' | 'total' | 'taxBreakdown' | 'productImages' |\n 'addItem' | 'removeItem' | 'updateQuantity' | 'toggleCart' | 'openCart' | 'closeCart' | 'checkout' | 'initCart' | 'syncCart' | 'clearCart'\n>\n\nexport function useCart() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCart must be used within <WhaleProvider>')\n\n return useStore(ctx.cartStore, useShallow((s) => ({\n cartId: s.cartId,\n items: s.items,\n itemCount: s.itemCount,\n subtotal: s.subtotal,\n taxAmount: s.taxAmount,\n total: s.total,\n taxBreakdown: s.taxBreakdown,\n cartOpen: s.cartOpen,\n cartLoading: s.cartLoading,\n productImages: s.productImages,\n addItem: s.addItem,\n removeItem: s.removeItem,\n updateQuantity: s.updateQuantity,\n toggleCart: s.toggleCart,\n openCart: s.openCart,\n closeCart: s.closeCart,\n initCart: s.initCart,\n syncCart: s.syncCart,\n clearCart: s.clearCart,\n checkout: s.checkout,\n })))\n}\n\n/** Granular selector — only re-renders on count change */\nexport function useCartItemCount(): number {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCartItemCount must be used within <WhaleProvider>')\n return useStore(ctx.cartStore, (s) => s.itemCount)\n}\n\n/** Granular selector — only re-renders on total change */\nexport function useCartTotal(): number {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCartTotal must be used within <WhaleProvider>')\n return useStore(ctx.cartStore, (s) => s.total)\n}\n","'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { useCart } from '../hooks/use-cart.js'\n\n/**\n * Hydrates cart from gateway on mount if a cartId is persisted.\n * Rendered internally by WhaleProvider.\n */\nexport function CartInitializer() {\n const { cartId, syncCart } = useCart()\n const initialized = useRef(false)\n\n useEffect(() => {\n if (initialized.current) return\n initialized.current = true\n if (cartId) {\n syncCart().catch(() => {\n // Cart may have expired — that's fine, addItem will auto-recover\n })\n }\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n return null\n}\n","'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { useAuth } from '../hooks/use-auth.js'\n\n/**\n * Restores auth session on mount — syncs persisted token to client.\n * Rendered internally by WhaleProvider.\n */\nexport function AuthInitializer() {\n const { restoreSession } = useAuth()\n const restored = useRef(false)\n\n useEffect(() => {\n if (restored.current) return\n restored.current = true\n restoreSession()\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n return null\n}\n","'use client'\n\nimport { useEffect, useRef, useContext } from 'react'\nimport { WhaleContext } from '../context.js'\nimport { PixelManager } from '../../pixels/pixel-manager.js'\nimport type { StorefrontConfig } from '../../pixels/types.js'\n\n/**\n * Fetches storefront pixel config on mount and initializes pixel providers.\n * Sets pixelManager on context so useAnalytics can dispatch events to it.\n * Rendered internally by WhaleProvider — storefronts don't need to add this manually.\n */\nexport function PixelInitializer({ onReady }: { onReady: (manager: PixelManager) => void }) {\n const ctx = useContext(WhaleContext)\n const initialized = useRef(false)\n\n useEffect(() => {\n if (!ctx || initialized.current) return\n if (typeof window === 'undefined') return\n if (!ctx.config.trackingEnabled) return\n initialized.current = true\n\n const { client } = ctx\n\n client.fetchStorefrontConfig().then(async (config: StorefrontConfig) => {\n if (!config.pixels || config.pixels.length === 0) return\n\n const manager = new PixelManager(config.pixels)\n await manager.initialize()\n onReady(manager)\n }).catch(() => {\n // Pixel config fetch failed — degrade silently\n })\n }, [ctx, onReady])\n\n return null\n}\n","'use client'\n\nimport { useMemo, useState, useCallback, type ReactNode } from 'react'\nimport { usePathname } from 'next/navigation'\nimport { WhaleClient } from '../client.js'\nimport type { WhaleStorefrontConfig, Product } from '../types.js'\nimport type { PixelManager } from '../pixels/pixel-manager.js'\nimport { WhaleContext, type WhaleContextValue } from './context.js'\nimport { createCartStore } from './stores/cart-store.js'\nimport { createAuthStore } from './stores/auth-store.js'\nimport { AnalyticsTracker } from './components/analytics-tracker.js'\nimport { CartInitializer } from './components/cart-initializer.js'\nimport { AuthInitializer } from './components/auth-initializer.js'\nimport { PixelInitializer } from './components/pixel-initializer.js'\n\n/** Read a boolean env var (NEXT_PUBLIC_*). Returns undefined when absent. */\nfunction envBool(name: string): boolean | undefined {\n if (typeof process === 'undefined') return undefined\n const raw = (process.env as Record<string, string | undefined>)[name]\n if (raw === undefined || raw === '') return undefined\n return raw !== '0' && raw.toLowerCase() !== 'false'\n}\n\n/** Read a numeric env var (NEXT_PUBLIC_*). Returns undefined when absent. */\nfunction envNumber(name: string): number | undefined {\n if (typeof process === 'undefined') return undefined\n const raw = (process.env as Record<string, string | undefined>)[name]\n if (raw === undefined || raw === '') return undefined\n const n = Number(raw)\n return Number.isFinite(n) ? n : undefined\n}\n\nexport interface WhaleProviderProps extends WhaleStorefrontConfig {\n children: ReactNode\n /** Server-fetched products passed to client for hooks */\n products?: Product[]\n}\n\nexport function WhaleProvider({\n children,\n products = [],\n storeId,\n apiKey,\n gatewayUrl,\n proxyPath,\n mediaSigningSecret,\n supabaseHost,\n storagePrefix,\n sessionTtl,\n debug,\n trackingEnabled,\n recordingRate,\n}: WhaleProviderProps) {\n const pathname = usePathname()\n const [pixelManager, setPixelManager] = useState<PixelManager | null>(null)\n\n const handlePixelReady = useCallback((manager: PixelManager) => {\n setPixelManager(manager)\n }, [])\n\n const ctx = useMemo<WhaleContextValue>(() => {\n const resolvedConfig = {\n storeId,\n apiKey,\n gatewayUrl: gatewayUrl || 'https://whale-gateway.fly.dev',\n proxyPath: proxyPath || '/api/gw',\n mediaSigningSecret: mediaSigningSecret || '',\n supabaseHost: supabaseHost || '',\n storagePrefix: storagePrefix || 'whale',\n sessionTtl: sessionTtl || 30 * 60 * 1000,\n debug: debug || false,\n trackingEnabled: trackingEnabled ?? envBool('NEXT_PUBLIC_TRACKING_ENABLED') ?? true,\n recordingRate: recordingRate ?? envNumber('NEXT_PUBLIC_RECORDING_RATE') ?? 0.1,\n }\n\n const client = new WhaleClient({\n storeId,\n apiKey,\n gatewayUrl: resolvedConfig.gatewayUrl,\n proxyPath: resolvedConfig.proxyPath,\n })\n\n // Analytics callbacks wired into cart store\n // These get called by the cart store on add/remove and fire analytics events.\n // We can't use the useAnalytics hook here (not in a component), so we use\n // the client directly — the AnalyticsTracker manages sessions.\n const cartStore = createCartStore(client, resolvedConfig.storagePrefix)\n const authStore = createAuthStore(client, resolvedConfig.storagePrefix)\n\n return {\n client,\n config: resolvedConfig,\n cartStore,\n authStore,\n products,\n pixelManager: null,\n }\n // Only recreate when identity changes — storeId + apiKey\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [storeId, apiKey])\n\n // Update products and pixelManager on the context when they change\n const value = useMemo<WhaleContextValue>(\n () => ({ ...ctx, products, pixelManager }),\n [ctx, products, pixelManager]\n )\n\n return (\n <WhaleContext.Provider value={value}>\n <AuthInitializer />\n <CartInitializer />\n <AnalyticsTracker pathname={pathname} />\n <PixelInitializer onReady={handlePixelReady} />\n {children}\n </WhaleContext.Provider>\n )\n}\n","'use client'\n\nimport { useContext, useState, useEffect, useMemo } from 'react'\nimport { WhaleContext } from '../context.js'\nimport type { Product } from '../../types.js'\n\n/**\n * Returns products passed via WhaleProvider.\n * Optionally filters by category or search.\n */\nexport function useProducts(opts?: {\n categoryId?: string\n search?: string\n}) {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useProducts must be used within <WhaleProvider>')\n\n const allProducts = ctx.products\n\n const products = useMemo(() => {\n let result = allProducts\n if (opts?.categoryId) {\n result = result.filter((p) => p.primary_category_id === opts.categoryId)\n }\n if (opts?.search) {\n const q = opts.search.toLowerCase()\n result = result.filter(\n (p) =>\n p.name.toLowerCase().includes(q) ||\n p.description?.toLowerCase().includes(q) ||\n p.slug.toLowerCase().includes(q)\n )\n }\n return result\n }, [allProducts, opts?.categoryId, opts?.search])\n\n return {\n products,\n allProducts,\n loading: false,\n }\n}\n\n/**\n * Returns a single product by slug from the provider's product list.\n */\nexport function useProduct(slug: string | null | undefined) {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useProduct must be used within <WhaleProvider>')\n\n const product = useMemo(() => {\n if (!slug) return null\n return ctx.products.find((p) => p.slug === slug) ?? null\n }, [ctx.products, slug])\n\n return {\n product,\n loading: false,\n }\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { WhaleContext } from '../context.js'\nimport type { WhaleClient } from '../../client.js'\n\nexport function useWhaleClient(): WhaleClient {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useWhaleClient must be used within <WhaleProvider>')\n return ctx.client\n}\n","'use client'\n\nimport { useContext, useState, useEffect, useCallback } from 'react'\nimport { useStore } from 'zustand'\nimport { WhaleContext } from '../context.js'\nimport type { Order, CustomerAnalytics } from '../../types.js'\n\nexport function useCustomerOrders() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCustomerOrders must be used within <WhaleProvider>')\n\n const customer = useStore(ctx.authStore, (s) => s.customer)\n const [orders, setOrders] = useState<Order[]>([])\n const [loading, setLoading] = useState(false)\n\n const refresh = useCallback(async () => {\n if (!customer?.id) {\n setOrders([])\n return\n }\n setLoading(true)\n try {\n const data = await ctx.client.getCustomerOrders(customer.id)\n setOrders(data)\n } catch {\n setOrders([])\n } finally {\n setLoading(false)\n }\n }, [customer?.id, ctx.client])\n\n useEffect(() => {\n refresh()\n }, [refresh])\n\n return { orders, loading, refresh }\n}\n\nexport function useCustomerAnalytics() {\n const ctx = useContext(WhaleContext)\n if (!ctx) throw new Error('useCustomerAnalytics must be used within <WhaleProvider>')\n\n const customer = useStore(ctx.authStore, (s) => s.customer)\n const [analytics, setAnalytics] = useState<CustomerAnalytics | null>(null)\n const [loading, setLoading] = useState(false)\n\n useEffect(() => {\n if (!customer?.id) {\n setAnalytics(null)\n return\n }\n setLoading(true)\n const name = `${customer.first_name} ${customer.last_name}`.trim()\n ctx.client\n .getCustomerAnalytics(customer.id, name || undefined)\n .then(setAnalytics)\n .catch(() => setAnalytics(null))\n .finally(() => setLoading(false))\n }, [customer?.id, customer?.first_name, customer?.last_name, ctx.client])\n\n return { analytics, loading }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neowhale/storefront",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "React/Next.js SDK for WhaleTools storefronts — cart, auth, analytics, and more",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"build": "tsup",
|
|
31
31
|
"dev": "tsup --watch",
|
|
32
32
|
"typecheck": "tsc --noEmit",
|
|
33
|
+
"test:e2e": "npx playwright test",
|
|
33
34
|
"prepublishOnly": "npm run build"
|
|
34
35
|
},
|
|
35
36
|
"keywords": [
|
|
@@ -42,6 +43,10 @@
|
|
|
42
43
|
],
|
|
43
44
|
"author": "WhaleTools <dev@whaletools.dev>",
|
|
44
45
|
"license": "MIT",
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/floradistro/neowhale-storefront"
|
|
49
|
+
},
|
|
45
50
|
"publishConfig": {
|
|
46
51
|
"access": "public"
|
|
47
52
|
},
|
|
@@ -57,12 +62,14 @@
|
|
|
57
62
|
}
|
|
58
63
|
},
|
|
59
64
|
"devDependencies": {
|
|
65
|
+
"@playwright/test": "^1.58.2",
|
|
60
66
|
"@types/node": "^22.0.0",
|
|
61
67
|
"@types/react": "^19.0.0",
|
|
62
68
|
"@types/react-dom": "^19.0.0",
|
|
63
69
|
"next": "^15.0.0",
|
|
64
70
|
"react": "^19.0.0",
|
|
65
71
|
"react-dom": "^19.0.0",
|
|
72
|
+
"serve": "^14.2.6",
|
|
66
73
|
"tsup": "^8.0.0",
|
|
67
74
|
"typescript": "^5.7.0",
|
|
68
75
|
"zustand": "^5.0.0"
|