@sonordev/site-kit 1.3.3 → 1.3.4

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.
Files changed (97) hide show
  1. package/dist/AnalyticsProvider-SC4YOBFI.js +25 -0
  2. package/dist/{AnalyticsProvider-PIUZBIOK.js.map → AnalyticsProvider-SC4YOBFI.js.map} +1 -1
  3. package/dist/AnalyticsProvider-ZVZ2SNZR.mjs +4 -0
  4. package/dist/{AnalyticsProvider-FX5TLRQC.mjs.map → AnalyticsProvider-ZVZ2SNZR.mjs.map} +1 -1
  5. package/dist/EngageWidget-RWBCI4RM.mjs +4 -0
  6. package/dist/{EngageWidget-R7YFQBS5.mjs.map → EngageWidget-RWBCI4RM.mjs.map} +1 -1
  7. package/dist/EngageWidget-T2S5WUMJ.js +13 -0
  8. package/dist/{EngageWidget-I4AZTKFY.js.map → EngageWidget-T2S5WUMJ.js.map} +1 -1
  9. package/dist/SitemapSync-6I5JTLER.js +13 -0
  10. package/dist/{SitemapSync-4FRADGXF.js.map → SitemapSync-6I5JTLER.js.map} +1 -1
  11. package/dist/SitemapSync-6L45DHRH.mjs +4 -0
  12. package/dist/{SitemapSync-IJRJ32Y3.mjs.map → SitemapSync-6L45DHRH.mjs.map} +1 -1
  13. package/dist/analytics/index.d.mts +6 -1
  14. package/dist/analytics/index.d.ts +6 -1
  15. package/dist/analytics/index.js +19 -69
  16. package/dist/analytics/index.js.map +1 -1
  17. package/dist/analytics/index.mjs +2 -67
  18. package/dist/analytics/index.mjs.map +1 -1
  19. package/dist/{chunk-NZHVGBAF.js → chunk-5DAALKHB.js} +5 -5
  20. package/dist/{chunk-NZHVGBAF.js.map → chunk-5DAALKHB.js.map} +1 -1
  21. package/dist/chunk-AU4GIQQU.mjs +69 -0
  22. package/dist/chunk-AU4GIQQU.mjs.map +1 -0
  23. package/dist/{chunk-3QQDXQJE.js → chunk-DK2WNYQA.js} +7 -7
  24. package/dist/chunk-DK2WNYQA.js.map +1 -0
  25. package/dist/{chunk-TK76624B.mjs → chunk-FP66BKW6.mjs} +6 -3
  26. package/dist/chunk-FP66BKW6.mjs.map +1 -0
  27. package/dist/chunk-FRN4JQXL.js +72 -0
  28. package/dist/chunk-FRN4JQXL.js.map +1 -0
  29. package/dist/{chunk-JAXKHEOM.js → chunk-GTLIGQDM.js} +6 -2
  30. package/dist/chunk-GTLIGQDM.js.map +1 -0
  31. package/dist/{chunk-EGZEZR2I.mjs → chunk-HNCSTGVK.mjs} +3 -4
  32. package/dist/chunk-HNCSTGVK.mjs.map +1 -0
  33. package/dist/{chunk-TLHRV3LZ.js → chunk-MSBWUOIU.js} +176 -2
  34. package/dist/chunk-MSBWUOIU.js.map +1 -0
  35. package/dist/{chunk-5TTTX6NN.mjs → chunk-RNOXXICL.mjs} +5 -5
  36. package/dist/{chunk-5TTTX6NN.mjs.map → chunk-RNOXXICL.mjs.map} +1 -1
  37. package/dist/{chunk-6YXRLC6W.mjs → chunk-SQXUPIMK.mjs} +176 -3
  38. package/dist/chunk-SQXUPIMK.mjs.map +1 -0
  39. package/dist/{chunk-JB6I5PYV.js → chunk-V2WSPLCN.js} +2 -4
  40. package/dist/chunk-V2WSPLCN.js.map +1 -0
  41. package/dist/{chunk-GADRLCYH.mjs → chunk-VZMRZQ2D.mjs} +7 -7
  42. package/dist/chunk-VZMRZQ2D.mjs.map +1 -0
  43. package/dist/{chunk-W2TZYAUL.mjs → chunk-WW2DKGBM.mjs} +3 -4
  44. package/dist/chunk-WW2DKGBM.mjs.map +1 -0
  45. package/dist/{chunk-UOBK3SSF.js → chunk-YBQT623Y.js} +2 -4
  46. package/dist/chunk-YBQT623Y.js.map +1 -0
  47. package/dist/commerce/index.d.mts +11 -4
  48. package/dist/commerce/index.d.ts +11 -4
  49. package/dist/commerce/index.js +48 -42
  50. package/dist/commerce/index.mjs +3 -1
  51. package/dist/commerce/server.d.mts +1 -1
  52. package/dist/commerce/server.d.ts +1 -1
  53. package/dist/engage/index.d.mts +35 -2
  54. package/dist/engage/index.d.ts +35 -2
  55. package/dist/engage/index.js +32 -5
  56. package/dist/engage/index.js.map +1 -1
  57. package/dist/engage/index.mjs +30 -1
  58. package/dist/engage/index.mjs.map +1 -1
  59. package/dist/forms/index.js +20 -1
  60. package/dist/forms/index.js.map +1 -1
  61. package/dist/forms/index.mjs +20 -1
  62. package/dist/forms/index.mjs.map +1 -1
  63. package/dist/index.d.mts +2 -2
  64. package/dist/index.d.ts +2 -2
  65. package/dist/index.js +45 -44
  66. package/dist/index.js.map +1 -1
  67. package/dist/index.mjs +6 -5
  68. package/dist/index.mjs.map +1 -1
  69. package/dist/layout/client.js +2 -2
  70. package/dist/layout/client.mjs +1 -1
  71. package/dist/layout/index.js +2 -2
  72. package/dist/layout/index.mjs +1 -1
  73. package/dist/seo/index.js +2 -2
  74. package/dist/seo/index.mjs +1 -1
  75. package/dist/sync/index.js +13 -19
  76. package/dist/sync/index.mjs +1 -1
  77. package/dist/{types-CGlnp43R.d.mts → types-CnIJF-kB.d.mts} +12 -1
  78. package/dist/{types-CGlnp43R.d.ts → types-CnIJF-kB.d.ts} +12 -1
  79. package/dist/{useEventModal-BVTx69XE.d.mts → useEventModal-BFhhrNfN.d.mts} +1 -1
  80. package/dist/{useEventModal-Dx1dItTJ.d.ts → useEventModal-Cp5mbphv.d.ts} +1 -1
  81. package/package.json +1 -1
  82. package/dist/AnalyticsProvider-FX5TLRQC.mjs +0 -4
  83. package/dist/AnalyticsProvider-PIUZBIOK.js +0 -21
  84. package/dist/EngageWidget-I4AZTKFY.js +0 -13
  85. package/dist/EngageWidget-R7YFQBS5.mjs +0 -4
  86. package/dist/SitemapSync-4FRADGXF.js +0 -19
  87. package/dist/SitemapSync-IJRJ32Y3.mjs +0 -4
  88. package/dist/chunk-3QQDXQJE.js.map +0 -1
  89. package/dist/chunk-6YXRLC6W.mjs.map +0 -1
  90. package/dist/chunk-EGZEZR2I.mjs.map +0 -1
  91. package/dist/chunk-GADRLCYH.mjs.map +0 -1
  92. package/dist/chunk-JAXKHEOM.js.map +0 -1
  93. package/dist/chunk-JB6I5PYV.js.map +0 -1
  94. package/dist/chunk-TK76624B.mjs.map +0 -1
  95. package/dist/chunk-TLHRV3LZ.js.map +0 -1
  96. package/dist/chunk-UOBK3SSF.js.map +0 -1
  97. package/dist/chunk-W2TZYAUL.mjs.map +0 -1
@@ -53,11 +53,11 @@ function SiteKitIdentityProvider({
53
53
  return /* @__PURE__ */ jsx(SiteKitIdentityContext.Provider, { value, children });
54
54
  }
55
55
  var LazyAnalyticsProvider = dynamic(
56
- () => import('./AnalyticsProvider-FX5TLRQC.mjs').then((m) => ({ default: m.AnalyticsProvider })),
56
+ () => import('./AnalyticsProvider-ZVZ2SNZR.mjs').then((m) => ({ default: m.AnalyticsProvider })),
57
57
  { ssr: false }
58
58
  );
59
59
  var LazyEngageWidget = dynamic(
60
- () => import('./EngageWidget-R7YFQBS5.mjs').then((m) => ({ default: m.EngageWidget })),
60
+ () => import('./EngageWidget-RWBCI4RM.mjs').then((m) => ({ default: m.EngageWidget })),
61
61
  { ssr: false }
62
62
  );
63
63
  var LazySignalBridge = dynamic(
@@ -65,7 +65,7 @@ var LazySignalBridge = dynamic(
65
65
  { ssr: false }
66
66
  );
67
67
  var LazySitemapSync = dynamic(
68
- () => import('./SitemapSync-IJRJ32Y3.mjs').then((m) => ({ default: m.SitemapSync })),
68
+ () => import('./SitemapSync-6L45DHRH.mjs').then((m) => ({ default: m.SitemapSync })),
69
69
  { ssr: false }
70
70
  );
71
71
  function SiteKitClientProviders({
@@ -152,5 +152,5 @@ function SiteKitClientProviders({
152
152
  }
153
153
 
154
154
  export { SiteKitClientProviders };
155
- //# sourceMappingURL=chunk-5TTTX6NN.mjs.map
156
- //# sourceMappingURL=chunk-5TTTX6NN.mjs.map
155
+ //# sourceMappingURL=chunk-RNOXXICL.mjs.map
156
+ //# sourceMappingURL=chunk-RNOXXICL.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/identity.tsx","../src/layout/SiteKitClientProviders.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-5TTTX6NN.mjs","sourcesContent":["/**\n * @sonordev/site-kit/shared — Unified Identity Management\n *\n * Single source of truth for visitor and session IDs across\n * Analytics, Signal, and Engage modules.\n *\n * Storage keys:\n * localStorage: _uptrade_vid (visitor ID, persists ~forever)\n * sessionStorage: _uptrade_sid (session ID, per-tab)\n * sessionStorage: _uptrade_stime (last activity timestamp for timeout)\n */\n\n'use client'\n\nimport React, { createContext, useContext, useMemo } from 'react'\n\n// ============================================\n// ID Generation\n// ============================================\n\nfunction generateId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID()\n }\n // Fallback for older environments\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)\n })\n}\n\n/**\n * Get or create a persistent visitor ID.\n * Stored in localStorage under `_uptrade_vid`.\n */\nexport function getOrCreateVisitorId(): string {\n if (typeof window === 'undefined') return ''\n\n const key = '_uptrade_vid'\n let visitorId = localStorage.getItem(key)\n\n if (!visitorId) {\n visitorId = generateId()\n localStorage.setItem(key, visitorId)\n }\n\n return visitorId\n}\n\n/**\n * Get or create a session ID with inactivity timeout.\n * Stored in sessionStorage under `_uptrade_sid`.\n * Session expires after `timeoutMinutes` of inactivity (default 30).\n */\nexport function getOrCreateSessionId(timeoutMinutes = 30): string {\n if (typeof window === 'undefined') return ''\n\n const key = '_uptrade_sid'\n const timeKey = '_uptrade_stime'\n const now = Date.now()\n const timeoutMs = timeoutMinutes * 60 * 1000\n\n const existingSession = sessionStorage.getItem(key)\n const lastActivity = sessionStorage.getItem(timeKey)\n\n if (existingSession && lastActivity) {\n const elapsed = now - parseInt(lastActivity, 10)\n if (elapsed < timeoutMs) {\n // Session still active — refresh timestamp\n sessionStorage.setItem(timeKey, now.toString())\n return existingSession\n }\n }\n\n // New session (first visit or timeout expired)\n const newSession = generateId()\n sessionStorage.setItem(key, newSession)\n sessionStorage.setItem(timeKey, now.toString())\n return newSession\n}\n\n// ============================================\n// React Context\n// ============================================\n\nexport interface SiteKitIdentity {\n visitorId: string\n sessionId: string\n}\n\nconst SiteKitIdentityContext = createContext<SiteKitIdentity | null>(null)\n\nexport interface SiteKitIdentityProviderProps {\n visitorId: string\n sessionId: string\n children: React.ReactNode\n}\n\nexport function SiteKitIdentityProvider({\n visitorId,\n sessionId,\n children,\n}: SiteKitIdentityProviderProps) {\n const value = useMemo(() => ({ visitorId, sessionId }), [visitorId, sessionId])\n\n return (\n <SiteKitIdentityContext.Provider value={value}>\n {children}\n </SiteKitIdentityContext.Provider>\n )\n}\n\n/**\n * Access the shared visitor/session identity.\n * Falls back to generating IDs directly if used outside of SiteKitIdentityProvider.\n */\nexport function useSiteKitIdentity(): SiteKitIdentity {\n const context = useContext(SiteKitIdentityContext)\n if (context) return context\n\n // Fallback for standalone usage outside SiteKitLayout\n return {\n visitorId: getOrCreateVisitorId(),\n sessionId: getOrCreateSessionId(),\n }\n}\n","'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) via\n * SiteKitIdentityProvider, ensuring consistent tracking across Analytics,\n * Signal, and Engage.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n SiteKitIdentityProvider,\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySignalBridge = dynamic(\n () => import('../signal/SignalBridge').then(m => ({ default: m.SignalBridge })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n sitemapSync?: boolean\n debug?: boolean\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = true,\n debug = false,\n}: SiteKitClientProvidersProps) {\n // Set window globals for modules that still read from them\n if (typeof window !== 'undefined') {\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = apiKey\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n }\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n let content = <>{children}</>\n\n // Wrap with SignalBridge if enabled\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n content = (\n <LazySignalBridge\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n >\n {content}\n </LazySignalBridge>\n )\n }\n\n // Wrap with Analytics if enabled\n if (analytics) {\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n content = (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n >\n {content}\n </LazyAnalyticsProvider>\n </Suspense>\n )\n }\n\n // Add Engage widget if enabled (renders alongside, doesn't wrap)\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n content = (\n <>\n {content}\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n position={engageConfig.position || 'bottom-right'}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n </>\n )\n }\n\n // Add SitemapSync if enabled\n if (sitemapSync) {\n content = (\n <>\n {content}\n <LazySitemapSync debug={debug} />\n </>\n )\n }\n\n return (\n <SiteKitIdentityProvider visitorId={visitorId} sessionId={sessionId}>\n {content}\n </SiteKitIdentityProvider>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/shared/identity.tsx","../src/layout/SiteKitClientProviders.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-RNOXXICL.mjs","sourcesContent":["/**\n * @sonordev/site-kit/shared — Unified Identity Management\n *\n * Single source of truth for visitor and session IDs across\n * Analytics, Signal, and Engage modules.\n *\n * Storage keys:\n * localStorage: _uptrade_vid (visitor ID, persists ~forever)\n * sessionStorage: _uptrade_sid (session ID, per-tab)\n * sessionStorage: _uptrade_stime (last activity timestamp for timeout)\n */\n\n'use client'\n\nimport React, { createContext, useContext, useMemo } from 'react'\n\n// ============================================\n// ID Generation\n// ============================================\n\nfunction generateId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID()\n }\n // Fallback for older environments\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)\n })\n}\n\n/**\n * Get or create a persistent visitor ID.\n * Stored in localStorage under `_uptrade_vid`.\n */\nexport function getOrCreateVisitorId(): string {\n if (typeof window === 'undefined') return ''\n\n const key = '_uptrade_vid'\n let visitorId = localStorage.getItem(key)\n\n if (!visitorId) {\n visitorId = generateId()\n localStorage.setItem(key, visitorId)\n }\n\n return visitorId\n}\n\n/**\n * Get or create a session ID with inactivity timeout.\n * Stored in sessionStorage under `_uptrade_sid`.\n * Session expires after `timeoutMinutes` of inactivity (default 30).\n */\nexport function getOrCreateSessionId(timeoutMinutes = 30): string {\n if (typeof window === 'undefined') return ''\n\n const key = '_uptrade_sid'\n const timeKey = '_uptrade_stime'\n const now = Date.now()\n const timeoutMs = timeoutMinutes * 60 * 1000\n\n const existingSession = sessionStorage.getItem(key)\n const lastActivity = sessionStorage.getItem(timeKey)\n\n if (existingSession && lastActivity) {\n const elapsed = now - parseInt(lastActivity, 10)\n if (elapsed < timeoutMs) {\n // Session still active — refresh timestamp\n sessionStorage.setItem(timeKey, now.toString())\n return existingSession\n }\n }\n\n // New session (first visit or timeout expired)\n const newSession = generateId()\n sessionStorage.setItem(key, newSession)\n sessionStorage.setItem(timeKey, now.toString())\n return newSession\n}\n\n// ============================================\n// React Context\n// ============================================\n\nexport interface SiteKitIdentity {\n visitorId: string\n sessionId: string\n}\n\nconst SiteKitIdentityContext = createContext<SiteKitIdentity | null>(null)\n\nexport interface SiteKitIdentityProviderProps {\n visitorId: string\n sessionId: string\n children: React.ReactNode\n}\n\nexport function SiteKitIdentityProvider({\n visitorId,\n sessionId,\n children,\n}: SiteKitIdentityProviderProps) {\n const value = useMemo(() => ({ visitorId, sessionId }), [visitorId, sessionId])\n\n return (\n <SiteKitIdentityContext.Provider value={value}>\n {children}\n </SiteKitIdentityContext.Provider>\n )\n}\n\n/**\n * Access the shared visitor/session identity.\n * Falls back to generating IDs directly if used outside of SiteKitIdentityProvider.\n */\nexport function useSiteKitIdentity(): SiteKitIdentity {\n const context = useContext(SiteKitIdentityContext)\n if (context) return context\n\n // Fallback for standalone usage outside SiteKitLayout\n return {\n visitorId: getOrCreateVisitorId(),\n sessionId: getOrCreateSessionId(),\n }\n}\n","'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) via\n * SiteKitIdentityProvider, ensuring consistent tracking across Analytics,\n * Signal, and Engage.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n SiteKitIdentityProvider,\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySignalBridge = dynamic(\n () => import('../signal/SignalBridge').then(m => ({ default: m.SignalBridge })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n sitemapSync?: boolean\n debug?: boolean\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = true,\n debug = false,\n}: SiteKitClientProvidersProps) {\n // Set window globals for modules that still read from them\n if (typeof window !== 'undefined') {\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = apiKey\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n }\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n let content = <>{children}</>\n\n // Wrap with SignalBridge if enabled\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n content = (\n <LazySignalBridge\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n >\n {content}\n </LazySignalBridge>\n )\n }\n\n // Wrap with Analytics if enabled\n if (analytics) {\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n content = (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n >\n {content}\n </LazyAnalyticsProvider>\n </Suspense>\n )\n }\n\n // Add Engage widget if enabled (renders alongside, doesn't wrap)\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n content = (\n <>\n {content}\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n position={engageConfig.position || 'bottom-right'}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n </>\n )\n }\n\n // Add SitemapSync if enabled\n if (sitemapSync) {\n content = (\n <>\n {content}\n <LazySitemapSync debug={debug} />\n </>\n )\n }\n\n return (\n <SiteKitIdentityProvider visitorId={visitorId} sessionId={sessionId}>\n {content}\n </SiteKitIdentityProvider>\n )\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  'use client';
2
+ import { useAnalyticsOptional } from './chunk-FP66BKW6.mjs';
2
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
4
  import React5, { useState, useEffect, useMemo, useRef, useCallback } from 'react';
4
5
 
@@ -1164,6 +1165,128 @@ function ProductEmbed({
1164
1165
  }
1165
1166
  ) });
1166
1167
  }
1168
+ var CM_PER_INCH = 2.54;
1169
+ function convertValue(value, fromUnit) {
1170
+ if (fromUnit === "inches") return Math.round(value * CM_PER_INCH * 10) / 10;
1171
+ return Math.round(value / CM_PER_INCH * 10) / 10;
1172
+ }
1173
+ function SizeChart({ chart, selectedSize, className }) {
1174
+ const [isOpen, setIsOpen] = useState(false);
1175
+ const [showAlt, setShowAlt] = useState(false);
1176
+ if (!chart?.measurements?.length || !chart?.rows?.length) return null;
1177
+ const primaryUnit = chart.unit;
1178
+ const altUnit = primaryUnit === "inches" ? "cm" : "inches";
1179
+ const activeUnit = showAlt ? altUnit : primaryUnit;
1180
+ const unitLabel = activeUnit === "cm" ? "cm" : "in";
1181
+ function getDisplayValues(row) {
1182
+ if (!showAlt) return row.values;
1183
+ if (row.values_alt && row.values_alt.length === row.values.length) {
1184
+ return row.values_alt;
1185
+ }
1186
+ return row.values.map((v) => convertValue(v, primaryUnit));
1187
+ }
1188
+ return /* @__PURE__ */ jsxs("div", { className, children: [
1189
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "10px" }, children: [
1190
+ /* @__PURE__ */ jsx(
1191
+ "button",
1192
+ {
1193
+ type: "button",
1194
+ onClick: () => setIsOpen(!isOpen),
1195
+ style: {
1196
+ background: "none",
1197
+ border: "none",
1198
+ padding: 0,
1199
+ cursor: "pointer",
1200
+ fontSize: "14px",
1201
+ color: "inherit",
1202
+ opacity: 0.7,
1203
+ textDecoration: "underline",
1204
+ textUnderlineOffset: "2px"
1205
+ },
1206
+ children: isOpen ? "Hide Size Chart" : "View Size Chart"
1207
+ }
1208
+ ),
1209
+ isOpen && /* @__PURE__ */ jsxs(
1210
+ "button",
1211
+ {
1212
+ type: "button",
1213
+ onClick: () => setShowAlt(!showAlt),
1214
+ style: {
1215
+ background: "none",
1216
+ border: "1px solid rgba(128,128,128,0.25)",
1217
+ borderRadius: "999px",
1218
+ padding: "2px 8px",
1219
+ cursor: "pointer",
1220
+ fontSize: "11px",
1221
+ lineHeight: 1.4,
1222
+ display: "flex",
1223
+ alignItems: "center",
1224
+ gap: 0
1225
+ },
1226
+ children: [
1227
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: showAlt ? 400 : 700, opacity: showAlt ? 0.45 : 1 }, children: "in" }),
1228
+ /* @__PURE__ */ jsx("span", { style: { margin: "0 3px", opacity: 0.3 }, children: "/" }),
1229
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: showAlt ? 700 : 400, opacity: showAlt ? 1 : 0.45 }, children: "cm" })
1230
+ ]
1231
+ }
1232
+ )
1233
+ ] }),
1234
+ isOpen && /* @__PURE__ */ jsx("div", { style: { marginTop: "12px", overflowX: "auto" }, children: /* @__PURE__ */ jsxs(
1235
+ "table",
1236
+ {
1237
+ style: {
1238
+ width: "100%",
1239
+ borderCollapse: "collapse",
1240
+ fontSize: "13px",
1241
+ lineHeight: 1.5
1242
+ },
1243
+ children: [
1244
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
1245
+ /* @__PURE__ */ jsx("th", { style: thStyle, children: "Size" }),
1246
+ chart.measurements.map((m) => /* @__PURE__ */ jsxs("th", { style: thStyle, children: [
1247
+ m,
1248
+ " ",
1249
+ /* @__PURE__ */ jsxs("span", { style: { opacity: 0.5, fontWeight: 400 }, children: [
1250
+ "(",
1251
+ unitLabel,
1252
+ ")"
1253
+ ] })
1254
+ ] }, m))
1255
+ ] }) }),
1256
+ /* @__PURE__ */ jsx("tbody", { children: chart.rows.map((row) => {
1257
+ const isSelected = selectedSize === row.size;
1258
+ const displayValues = getDisplayValues(row);
1259
+ return /* @__PURE__ */ jsxs(
1260
+ "tr",
1261
+ {
1262
+ style: {
1263
+ backgroundColor: isSelected ? "rgba(57, 191, 176, 0.08)" : void 0
1264
+ },
1265
+ children: [
1266
+ /* @__PURE__ */ jsx("td", { style: { ...tdStyle, fontWeight: 600 }, children: row.size }),
1267
+ displayValues.map((v, i) => /* @__PURE__ */ jsx("td", { style: tdStyle, children: v }, i))
1268
+ ]
1269
+ },
1270
+ row.size
1271
+ );
1272
+ }) })
1273
+ ]
1274
+ }
1275
+ ) })
1276
+ ] });
1277
+ }
1278
+ var thStyle = {
1279
+ padding: "8px 12px",
1280
+ textAlign: "left",
1281
+ fontWeight: 600,
1282
+ borderBottom: "1px solid rgba(128, 128, 128, 0.2)",
1283
+ whiteSpace: "nowrap"
1284
+ };
1285
+ var tdStyle = {
1286
+ padding: "8px 12px",
1287
+ borderBottom: "1px solid rgba(128, 128, 128, 0.1)",
1288
+ whiteSpace: "nowrap"
1289
+ };
1167
1290
  function ProductDetail({
1168
1291
  product: propProduct,
1169
1292
  slug,
@@ -1189,6 +1312,20 @@ function ProductDetail({
1189
1312
  const [quantity, setQuantity] = useState(1);
1190
1313
  const [selectedImage, setSelectedImage] = useState(0);
1191
1314
  const [checkingOut, setCheckingOut] = useState(false);
1315
+ const analytics = useAnalyticsOptional();
1316
+ useEffect(() => {
1317
+ if (!product || !analytics) return;
1318
+ analytics.trackEvent({
1319
+ name: "product_view",
1320
+ properties: {
1321
+ offering_id: product.id,
1322
+ name: product.name,
1323
+ price: product.price,
1324
+ type: product.type,
1325
+ category: product.category?.name
1326
+ }
1327
+ });
1328
+ }, [product?.id, analytics]);
1192
1329
  useEffect(() => {
1193
1330
  if (propProduct) {
1194
1331
  setProduct(propProduct);
@@ -1251,11 +1388,31 @@ function ProductDetail({
1251
1388
  const isLowStock = product.track_inventory && inventoryCount !== void 0 && inventoryCount > 0 && inventoryCount <= 5;
1252
1389
  const needsVariantSelection = (product.is_clothing || (product.variants?.length ?? 0) > 0) && !selectedVariant;
1253
1390
  const handleAddToCart = () => {
1391
+ analytics?.trackEvent({
1392
+ name: "add_to_cart",
1393
+ properties: {
1394
+ offering_id: product.id,
1395
+ variant_id: selectedVariant?.id,
1396
+ quantity,
1397
+ price: selectedVariant?.price ?? product.price,
1398
+ name: product.name
1399
+ }
1400
+ });
1254
1401
  if (onAddToCart) {
1255
1402
  onAddToCart(product, selectedVariant, quantity);
1256
1403
  }
1257
1404
  };
1258
1405
  const handleBuyNow = async () => {
1406
+ analytics?.trackEvent({
1407
+ name: "add_to_cart",
1408
+ properties: {
1409
+ offering_id: product.id,
1410
+ variant_id: selectedVariant?.id,
1411
+ quantity,
1412
+ price: selectedVariant?.price ?? product.price,
1413
+ name: product.name
1414
+ }
1415
+ });
1259
1416
  if (onBuyNow) {
1260
1417
  onBuyNow(product, selectedVariant, quantity);
1261
1418
  return;
@@ -1432,6 +1589,13 @@ function ProductDetail({
1432
1589
  );
1433
1590
  }) })
1434
1591
  ] }),
1592
+ product.is_clothing && product.size_chart && /* @__PURE__ */ jsx("div", { style: { marginTop: "0.75rem" }, children: /* @__PURE__ */ jsx(
1593
+ SizeChart,
1594
+ {
1595
+ chart: product.size_chart,
1596
+ selectedSize: selectedVariant?.options?.["Size"]
1597
+ }
1598
+ ) }),
1435
1599
  showQuantity && !isOutOfStock && /* @__PURE__ */ jsxs("div", { className: "site-kit-product-detail__quantity", style: { marginTop: "1.5rem" }, children: [
1436
1600
  /* @__PURE__ */ jsx("label", { style: {
1437
1601
  display: "block",
@@ -2175,6 +2339,7 @@ function CheckoutForm({
2175
2339
  phone: ""
2176
2340
  });
2177
2341
  const isProduct = offering.type === "product";
2342
+ const analytics = useAnalyticsOptional();
2178
2343
  useEffect(() => {
2179
2344
  fetchProcessorConfig().then((config) => {
2180
2345
  if (config?.processor) setProcessor(config.processor);
@@ -2216,6 +2381,14 @@ function CheckoutForm({
2216
2381
  e.preventDefault();
2217
2382
  setLoading(true);
2218
2383
  setError(null);
2384
+ analytics?.trackEvent({
2385
+ name: "checkout_start",
2386
+ properties: {
2387
+ offering_id: offering.id,
2388
+ total,
2389
+ quantity
2390
+ }
2391
+ });
2219
2392
  try {
2220
2393
  if (actualMode === "register" && isEvent && scheduleId) {
2221
2394
  const result = await registerForEvent(offering.id, scheduleId, customer);
@@ -4418,6 +4591,6 @@ function getApiKey() {
4418
4591
  return "";
4419
4592
  }
4420
4593
 
4421
- export { CalendarView, CheckoutForm, EventCalendar, EventEmbed, EventModal, EventTile, EventsWidget, OfferingCard, OfferingList, ProductDetail, ProductEmbed, ProductGrid, ProductPage, RegistrationForm, UpcomingEvents, createCheckoutSession, fetchActiveProcessor, fetchCategories, fetchLatestOffering, fetchNextEvent, fetchOffering, fetchOfferings, fetchProcessorConfig, fetchProductBySlug, fetchProducts, fetchProductsPublic, fetchServices, fetchShippingRates, fetchUpcomingEvents, formatDate, formatDateRange, formatDateTime, formatPrice, formatTime, getOfferingUrl, getRelativeTimeUntil, getSpotsRemaining, isEventSoldOut, registerForEvent, useEventModal, validateAddress };
4422
- //# sourceMappingURL=chunk-6YXRLC6W.mjs.map
4423
- //# sourceMappingURL=chunk-6YXRLC6W.mjs.map
4594
+ export { CalendarView, CheckoutForm, EventCalendar, EventEmbed, EventModal, EventTile, EventsWidget, OfferingCard, OfferingList, ProductDetail, ProductEmbed, ProductGrid, ProductPage, RegistrationForm, SizeChart, UpcomingEvents, createCheckoutSession, fetchActiveProcessor, fetchCategories, fetchLatestOffering, fetchNextEvent, fetchOffering, fetchOfferings, fetchProcessorConfig, fetchProductBySlug, fetchProducts, fetchProductsPublic, fetchServices, fetchShippingRates, fetchUpcomingEvents, formatDate, formatDateRange, formatDateTime, formatPrice, formatTime, getOfferingUrl, getRelativeTimeUntil, getSpotsRemaining, isEventSoldOut, registerForEvent, useEventModal, validateAddress };
4595
+ //# sourceMappingURL=chunk-SQXUPIMK.mjs.map
4596
+ //# sourceMappingURL=chunk-SQXUPIMK.mjs.map