@metodokorexmk/tracking 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/analytics.ts","../src/core/gtm.ts","../src/trackers/video-tracker.ts","../src/trackers/events.ts","../src/trackers/wistia-adapter.ts","../src/trackers/voomly-adapter.ts","../src/trackers/html5-adapter.ts","../src/orchestrator/landing-tracker.ts","../src/persistence/api-client.ts","../src/persistence/lead-submission.ts","../src/persistence/dwell-time-tracker.ts","../src/persistence/tracking-queries.ts"],"names":["createStats"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Core de Google Analytics 4\r\n * Inicialización, tracking de eventos y captura de datos del visitante.\r\n * Desacoplado de cualquier framework (Next.js, React, etc.)\r\n */\r\n\r\nimport ReactGA from 'react-ga4';\r\nimport type { TrackingConfig, UTMParams, TrackingEventData } from './types';\r\n\r\n// ====================================\r\n// ESTADO INTERNO\r\n// ====================================\r\n\r\nlet isInitialized = false;\r\nlet currentConfig: TrackingConfig = {};\r\nlet resolvedTrackingId: string = '';\r\nlet cachedUserId: string | null = null;\r\nlet cachedUserName: string | null = null;\r\n\r\n// ====================================\r\n// RESOLUCIÓN DE GA TRACKING ID\r\n// ====================================\r\n\r\n/**\r\n * Obtiene el GA Tracking ID actual.\r\n * Si se configuró un `resolveTrackingId`, lo usa dinámicamente.\r\n * Si no, usa el `trackingId` fijo de la config.\r\n */\r\nexport const getGATrackingId = (): string => {\r\n if (typeof window === 'undefined') return resolvedTrackingId || '';\r\n\r\n if (currentConfig.resolveTrackingId) {\r\n try {\r\n const path = window.location.pathname;\r\n return currentConfig.resolveTrackingId(path);\r\n } catch {\r\n // fallback si la función falla\r\n }\r\n }\r\n\r\n return resolvedTrackingId;\r\n};\r\n\r\n// ====================================\r\n// INICIALIZACIÓN\r\n// ====================================\r\n\r\n/**\r\n * Inicializa Google Analytics con la configuración proporcionada.\r\n *\r\n * @example\r\n * ```ts\r\n * // Con ID fijo\r\n * initGA({ trackingId: 'G-XXXXXXX' })\r\n *\r\n * // Con resolución dinámica\r\n * initGA({\r\n * resolveTrackingId: (path) => {\r\n * if (path.startsWith('/kin')) return 'G-KIN-ID'\r\n * return localStorage.getItem('user_GA_id') || 'G-DEFAULT'\r\n * }\r\n * })\r\n * ```\r\n */\r\nexport const initGA = (config: TrackingConfig = {}): void => {\r\n if (typeof window === 'undefined') return;\r\n if (isInitialized) return;\r\n\r\n currentConfig = config;\r\n resolvedTrackingId = config.trackingId || '';\r\n\r\n const trackingId = getGATrackingId();\r\n if (!trackingId) {\r\n if (config.debug) {\r\n // eslint-disable-next-line no-console\r\n console.warn('[KorexTracking] No tracking ID provided. GA4 will not initialize.');\r\n }\r\n return;\r\n }\r\n\r\n try {\r\n ReactGA.initialize(trackingId);\r\n isInitialized = true;\r\n\r\n if (config.anonymizeIp) {\r\n window.gtag?.('config', trackingId, { anonymize_ip: true });\r\n }\r\n\r\n if (config.debug) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[KorexTracking] GA4 initialized with ID: ${trackingId}`);\r\n }\r\n } catch (error) {\r\n if (config.debug) {\r\n // eslint-disable-next-line no-console\r\n console.error('[KorexTracking] Failed to initialize GA4:', error);\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Reinicializa GA con un nuevo Tracking ID.\r\n * Útil cuando el ID cambia dinámicamente (ej. login del usuario).\r\n */\r\nexport const reinitGA = (newTrackingId: string): void => {\r\n isInitialized = false;\r\n resolvedTrackingId = newTrackingId;\r\n initGA({ ...currentConfig, trackingId: newTrackingId });\r\n};\r\n\r\n/**\r\n * Verificar si GA está inicializado\r\n */\r\nexport const isGAInitialized = (): boolean => isInitialized;\r\n\r\n// ====================================\r\n// CAPTURA DE DATOS DEL VISITANTE\r\n// ====================================\r\n\r\n/**\r\n * Extrae los parámetros UTM de la URL actual.\r\n */\r\nexport const captureUTMParams = (): UTMParams | null => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n const params = new URLSearchParams(window.location.search);\r\n const utmParams: UTMParams = {};\r\n let hasParams = false;\r\n\r\n const utmKeys: (keyof UTMParams)[] = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];\r\n\r\n for (const key of utmKeys) {\r\n const value = params.get(key);\r\n if (value) {\r\n utmParams[key] = value;\r\n hasParams = true;\r\n }\r\n }\r\n\r\n return hasParams ? utmParams : null;\r\n};\r\n\r\n/**\r\n * Captura el `user_id` desde la URL (?user_id=xxx).\r\n * Lo cachea internamente para enviarlo en todos los eventos.\r\n */\r\nexport const captureUserIdFromURL = (): string | null => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n const params = new URLSearchParams(window.location.search);\r\n const userId = params.get('user_id') || params.get('userId');\r\n\r\n if (userId) {\r\n cachedUserId = userId;\r\n try {\r\n localStorage.setItem('tracking_user_id', userId);\r\n } catch {\r\n // localStorage puede no estar disponible\r\n }\r\n }\r\n\r\n return userId;\r\n};\r\n\r\n/**\r\n * Resuelve el nombre del usuario desde múltiples fuentes.\r\n * Prioridad: URL > localStorage > null\r\n */\r\nexport const getUserName = (): string | null => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n // 1. Desde URL\r\n const params = new URLSearchParams(window.location.search);\r\n const fromUrl = params.get('user_name') || params.get('userName');\r\n if (fromUrl) {\r\n cachedUserName = fromUrl;\r\n return fromUrl;\r\n }\r\n\r\n // 2. Desde cache interno\r\n if (cachedUserName) return cachedUserName;\r\n\r\n // 3. Desde localStorage\r\n try {\r\n const fromStorage = localStorage.getItem('tracking_user_name');\r\n if (fromStorage) {\r\n cachedUserName = fromStorage;\r\n return fromStorage;\r\n }\r\n\r\n const userInfo = localStorage.getItem('userInfo');\r\n if (userInfo) {\r\n const parsed = JSON.parse(userInfo);\r\n const name = parsed?.name || parsed?.userName || parsed?.fullName;\r\n if (name) {\r\n cachedUserName = name;\r\n return name;\r\n }\r\n }\r\n } catch {\r\n // localStorage puede no estar disponible\r\n }\r\n\r\n return null;\r\n};\r\n\r\n/**\r\n * Obtiene el user_id cacheado.\r\n */\r\nexport const getUserId = (): string | null => {\r\n if (cachedUserId) return cachedUserId;\r\n\r\n if (typeof window === 'undefined') return null;\r\n\r\n try {\r\n return localStorage.getItem('tracking_user_id');\r\n } catch {\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * Establece manualmente el user_id (ej. después de login).\r\n */\r\nexport const setUserId = (userId: string): void => {\r\n cachedUserId = userId;\r\n try {\r\n localStorage.setItem('tracking_user_id', userId);\r\n } catch {\r\n // ignore\r\n }\r\n // Configurar en GA4 como user property\r\n window.gtag?.('set', { user_id: userId });\r\n};\r\n\r\n/**\r\n * Establece manualmente el user_name.\r\n */\r\nexport const setUserName = (userName: string): void => {\r\n cachedUserName = userName;\r\n try {\r\n localStorage.setItem('tracking_user_name', userName);\r\n } catch {\r\n // ignore\r\n }\r\n};\r\n\r\n// ====================================\r\n// TRACKING DE PÁGINAS\r\n// ====================================\r\n\r\n/**\r\n * Envía un pageview a GA4.\r\n * Automáticamente incluye UTM params y user_id si están disponibles.\r\n */\r\nexport const trackPageView = (path: string): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const userId = getUserId();\r\n const utmParams = captureUTMParams();\r\n\r\n // Construir path con UTMs si existen\r\n let pageWithParams = path;\r\n if (utmParams) {\r\n const searchParams = new URLSearchParams();\r\n Object.entries(utmParams).forEach(([key, value]) => {\r\n if (value) searchParams.set(key, value);\r\n });\r\n const paramString = searchParams.toString();\r\n if (paramString) {\r\n pageWithParams = `${path}${path.includes('?') ? '&' : '?'}${paramString}`;\r\n }\r\n }\r\n\r\n // Enviar por ReactGA\r\n try {\r\n ReactGA.send({\r\n hitType: 'pageview',\r\n page: pageWithParams,\r\n ...(userId && { user_id: userId }),\r\n });\r\n } catch {\r\n // ReactGA puede fallar si GA4 no está cargado (ad-blockers, carga lenta, etc.)\r\n }\r\n\r\n // Enviar por gtag nativo\r\n try {\r\n window.gtag?.('event', 'page_view', {\r\n page_path: pageWithParams,\r\n page_title: document.title,\r\n ...(userId && { user_id: userId }),\r\n });\r\n } catch {\r\n // gtag puede no estar disponible\r\n }\r\n\r\n if (currentConfig.debug) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[KorexTracking] PageView: ${pageWithParams}`, { userId });\r\n }\r\n};\r\n\r\n// ====================================\r\n// TRACKING DE EVENTOS\r\n// ====================================\r\n\r\n/**\r\n * Envía un evento personalizado a GA4.\r\n * Usa envío dual: `window.gtag()` + `ReactGA.event()`.\r\n * Siempre incluye `user_id` y `user_name` como parámetros.\r\n *\r\n * @example\r\n * ```ts\r\n * trackEvent('CTA', 'click', 'Botón Hero', undefined, { section: 'hero' })\r\n * ```\r\n */\r\nexport const trackEvent = (category: string, action: string, label?: string, value?: number, additionalData?: TrackingEventData): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const userId = getUserId();\r\n const userName = getUserName();\r\n\r\n const eventData: TrackingEventData = {\r\n event_category: category,\r\n event_label: label || '',\r\n ...(value !== undefined && { value }),\r\n ...(userId && { user_id: userId }),\r\n ...(userName && { user_name: userName }),\r\n timestamp: Date.now(),\r\n ...additionalData,\r\n };\r\n\r\n // 1. Enviar por gtag nativo (más fiable)\r\n try {\r\n window.gtag?.('event', action, eventData);\r\n } catch {\r\n // ignore\r\n }\r\n\r\n // 2. Enviar por ReactGA como fallback\r\n try {\r\n ReactGA.event({\r\n category,\r\n action,\r\n label: label || undefined,\r\n value: value || undefined,\r\n ...(userId && { user_id: userId }),\r\n });\r\n } catch {\r\n // ignore\r\n }\r\n\r\n if (currentConfig.debug) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[KorexTracking] Event: ${category}/${action}`, eventData);\r\n }\r\n};\r\n\r\n// ====================================\r\n// UTILIDADES\r\n// ====================================\r\n\r\n/**\r\n * Resetea el estado interno (útil para tests y re-inicialización).\r\n */\r\nexport const resetAnalytics = (): void => {\r\n isInitialized = false;\r\n currentConfig = {};\r\n resolvedTrackingId = '';\r\n cachedUserId = null;\r\n cachedUserName = null;\r\n};\r\n","/**\r\n * Google Tag Manager — Carga e inyección vanilla (sin Next.js)\r\n * Proporciona pushToDataLayer e injectGTMScript.\r\n */\r\n\r\n/**\r\n * Inyecta el script de Google Tag Manager en el <head> del documento.\r\n * Equivalente al componente <Script> de Next.js, pero framework-agnostic.\r\n *\r\n * @param gtmId - ID de GTM (ej: 'GTM-5GMQNFMN')\r\n *\r\n * @example\r\n * ```ts\r\n * injectGTMScript('GTM-5GMQNFMN')\r\n * ```\r\n */\r\nexport const injectGTMScript = (gtmId: string): void => {\r\n if (typeof window === 'undefined') return;\r\n if (!gtmId) return;\r\n\r\n // Evitar inyección duplicada\r\n const existingScript = document.querySelector(`script[data-gtm-id=\"${gtmId}\"]`);\r\n if (existingScript) return;\r\n\r\n // Inicializar dataLayer\r\n window.dataLayer = window.dataLayer || [];\r\n window.dataLayer.push({\r\n 'gtm.start': new Date().getTime(),\r\n event: 'gtm.js',\r\n });\r\n\r\n // Crear e inyectar el script\r\n const script = document.createElement('script');\r\n script.async = true;\r\n script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;\r\n script.setAttribute('data-gtm-id', gtmId);\r\n\r\n const firstScript = document.getElementsByTagName('script')[0];\r\n if (firstScript?.parentNode) {\r\n firstScript.parentNode.insertBefore(script, firstScript);\r\n } else {\r\n document.head.appendChild(script);\r\n }\r\n\r\n // Inyectar noscript fallback en body\r\n if (document.body) {\r\n const noscript = document.createElement('noscript');\r\n const iframe = document.createElement('iframe');\r\n iframe.src = `https://www.googletagmanager.com/ns.html?id=${gtmId}`;\r\n iframe.height = '0';\r\n iframe.width = '0';\r\n iframe.style.display = 'none';\r\n iframe.style.visibility = 'hidden';\r\n noscript.appendChild(iframe);\r\n document.body.insertBefore(noscript, document.body.firstChild);\r\n }\r\n};\r\n\r\n/**\r\n * Envía un evento al dataLayer de GTM.\r\n *\r\n * @param eventName - Nombre del evento\r\n * @param data - Datos adicionales del evento\r\n *\r\n * @example\r\n * ```ts\r\n * pushToDataLayer('page_view', { page_path: '/kin' })\r\n * pushToDataLayer('cta_click', { button_text: 'Únete', section: 'hero' })\r\n * ```\r\n */\r\nexport const pushToDataLayer = (eventName: string, data?: Record<string, unknown>): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n window.dataLayer = window.dataLayer || [];\r\n window.dataLayer.push({\r\n event: eventName,\r\n ...data,\r\n });\r\n};\r\n","/**\r\n * VideoTracker — Tracking avanzado de video para GA4\r\n * Gestiona el estado de reproducción por video y emite eventos a Google Analytics.\r\n * Framework-agnostic (no requiere React).\r\n */\r\n\r\nimport { trackEvent } from '../core/analytics';\r\nimport type { VideoTrackingState } from '../core/types';\r\n\r\nexport class VideoTracker {\r\n private videos: Map<string, VideoTrackingState> = new Map();\r\n private watchTimeIntervals: Map<string, ReturnType<typeof setInterval>> = new Map();\r\n\r\n /**\r\n * Inicializa el tracking para un video.\r\n */\r\n initVideo(videoId: string): void {\r\n if (this.videos.has(videoId)) return;\r\n\r\n const state: VideoTrackingState = {\r\n videoId,\r\n startTime: Date.now(),\r\n totalWatchTime: 0,\r\n playCount: 0,\r\n pauseCount: 0,\r\n seekCount: 0,\r\n completionPercentage: 0,\r\n lastPlayTimestamp: 0,\r\n isPlaying: false,\r\n currentTime: 0,\r\n duration: 0,\r\n pauseTimes: [],\r\n seekEvents: [],\r\n progressMilestones: new Set(),\r\n playbackSpeed: 1,\r\n };\r\n\r\n this.videos.set(videoId, state);\r\n\r\n trackEvent('Video', 'init', videoId, undefined, {\r\n video_id: videoId,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de evento play.\r\n */\r\n trackPlay(videoId: string, currentTime: number = 0): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.playCount++;\r\n state.isPlaying = true;\r\n state.lastPlayTimestamp = Date.now();\r\n state.currentTime = currentTime;\r\n\r\n // Iniciar conteo de tiempo de reproducción\r\n this.startWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'play', videoId, undefined, {\r\n video_id: videoId,\r\n play_count: state.playCount,\r\n current_time: Math.round(currentTime),\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de evento pause.\r\n */\r\n trackPause(videoId: string, currentTime: number, duration?: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.pauseCount++;\r\n state.isPlaying = false;\r\n state.currentTime = currentTime;\r\n state.pauseTimes.push(currentTime);\r\n\r\n if (duration) {\r\n state.duration = duration;\r\n state.completionPercentage = Math.round((currentTime / duration) * 100);\r\n }\r\n\r\n // Detener conteo de tiempo\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'pause', videoId, undefined, {\r\n video_id: videoId,\r\n pause_count: state.pauseCount,\r\n current_time: Math.round(currentTime),\r\n completion_percentage: state.completionPercentage,\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de evento seek (saltar en el timeline).\r\n */\r\n trackSeek(videoId: string, fromTime: number, toTime: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.seekCount++;\r\n state.seekEvents.push({ from: fromTime, to: toTime });\r\n\r\n trackEvent('Video', 'seek', videoId, undefined, {\r\n video_id: videoId,\r\n seek_count: state.seekCount,\r\n from_time: Math.round(fromTime),\r\n to_time: Math.round(toTime),\r\n skip_duration: Math.round(toTime - fromTime),\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de progreso (milestones: 25%, 50%, 75%).\r\n */\r\n trackProgress(videoId: string, percentage: number, currentTime: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n const milestone = Math.floor(percentage / 25) * 25;\r\n\r\n // Solo emitir cada milestone una vez\r\n if (milestone > 0 && milestone < 100 && !state.progressMilestones.has(milestone)) {\r\n state.progressMilestones.add(milestone);\r\n\r\n trackEvent('Video', 'progress', videoId, milestone, {\r\n video_id: videoId,\r\n progress_percentage: milestone,\r\n current_time: Math.round(currentTime),\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Tracking de completación del video (≥95%).\r\n */\r\n trackComplete(videoId: string, totalDuration: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.completionPercentage = 100;\r\n state.duration = totalDuration;\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'complete', videoId, undefined, {\r\n video_id: videoId,\r\n total_duration: Math.round(totalDuration),\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n play_count: state.playCount,\r\n pause_count: state.pauseCount,\r\n seek_count: state.seekCount,\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de fin del video (evento ended nativo).\r\n */\r\n trackEnd(videoId: string): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.isPlaying = false;\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'end', videoId, undefined, {\r\n video_id: videoId,\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n play_count: state.playCount,\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de cambio de velocidad de reproducción.\r\n */\r\n trackSpeedChange(videoId: string, speed: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n state.playbackSpeed = speed;\r\n\r\n trackEvent('Video', 'speed_change', videoId, undefined, {\r\n video_id: videoId,\r\n playback_speed: speed,\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de pantalla completa.\r\n */\r\n trackFullscreen(videoId: string, isFullscreen: boolean): void {\r\n trackEvent('Video', isFullscreen ? 'fullscreen_enter' : 'fullscreen_exit', videoId, undefined, {\r\n video_id: videoId,\r\n is_fullscreen: isFullscreen,\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de no interacción (el usuario está en la página pero no interactúa con el video).\r\n */\r\n trackNoInteraction(videoId: string, timeOnPage: number): void {\r\n trackEvent('Video', 'no_interaction', videoId, undefined, {\r\n video_id: videoId,\r\n time_on_page: Math.round(timeOnPage),\r\n });\r\n }\r\n\r\n /**\r\n * Obtiene el estado actual de un video.\r\n */\r\n getState(videoId: string): VideoTrackingState | undefined {\r\n return this.videos.get(videoId);\r\n }\r\n\r\n /**\r\n * Limpia el tracking de un video específico.\r\n */\r\n cleanup(videoId: string): void {\r\n this.stopWatchTimeTracking(videoId);\r\n this.videos.delete(videoId);\r\n }\r\n\r\n /**\r\n * Limpia todo el tracking.\r\n */\r\n cleanupAll(): void {\r\n for (const videoId of this.videos.keys()) {\r\n this.stopWatchTimeTracking(videoId);\r\n }\r\n this.videos.clear();\r\n }\r\n\r\n // --- Métodos privados ---\r\n\r\n private getOrCreateState(videoId: string): VideoTrackingState {\r\n if (!this.videos.has(videoId)) {\r\n this.initVideo(videoId);\r\n }\r\n return this.videos.get(videoId)!;\r\n }\r\n\r\n private startWatchTimeTracking(videoId: string): void {\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n const interval = setInterval(() => {\r\n const state = this.videos.get(videoId);\r\n if (state?.isPlaying) {\r\n state.totalWatchTime += 1;\r\n }\r\n }, 1000);\r\n\r\n this.watchTimeIntervals.set(videoId, interval);\r\n }\r\n\r\n private stopWatchTimeTracking(videoId: string): void {\r\n const interval = this.watchTimeIntervals.get(videoId);\r\n if (interval) {\r\n clearInterval(interval);\r\n this.watchTimeIntervals.delete(videoId);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Instancia singleton del VideoTracker.\r\n * Usar cuando se necesita una sola instancia global.\r\n */\r\nexport const videoTracker = new VideoTracker();\r\n","/**\r\n * Funciones genéricas de tracking de eventos para GA4.\r\n * Cada función es una abstracción de `trackEvent()` con categoría y acción predefinidas.\r\n */\r\n\r\nimport { trackEvent } from '../core/analytics';\r\nimport type { TrackingEventData } from '../core/types';\r\n\r\n// ====================================\r\n// CTA / BOTONES\r\n// ====================================\r\n\r\nexport const trackCTAClick = (buttonName: string, section: string, additionalData?: TrackingEventData): void => {\r\n trackEvent('CTA', 'click', buttonName, undefined, {\r\n button_name: buttonName,\r\n section,\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// FORMULARIOS\r\n// ====================================\r\n\r\nexport const trackFormStart = (formName: string): void => {\r\n trackEvent('Form', 'started', formName, undefined, {\r\n form_name: formName,\r\n timestamp: Date.now(),\r\n });\r\n};\r\n\r\nexport const trackFormFieldComplete = (formName: string, fieldName: string): void => {\r\n trackEvent('Form', 'field_completed', formName, undefined, {\r\n form_name: formName,\r\n field_name: fieldName,\r\n });\r\n};\r\n\r\nexport const trackFormSubmit = (formName: string, success: boolean, additionalData?: TrackingEventData): void => {\r\n trackEvent('Form', success ? 'submit_success' : 'submit_error', formName, undefined, {\r\n form_name: formName,\r\n success,\r\n ...additionalData,\r\n });\r\n};\r\n\r\nexport const trackFormValidationError = (formName: string, fieldName: string, errorMessage: string): void => {\r\n trackEvent('Error', 'validation', formName, undefined, {\r\n form_name: formName,\r\n field_name: fieldName,\r\n error_message: errorMessage,\r\n });\r\n};\r\n\r\n// ====================================\r\n// CONVERSIONES\r\n// ====================================\r\n\r\nexport const trackConversion = (conversionType: string, value?: number, additionalData?: TrackingEventData): void => {\r\n trackEvent('Conversion', conversionType, undefined, value, {\r\n conversion_type: conversionType,\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// REDES SOCIALES\r\n// ====================================\r\n\r\nexport const trackSocialClick = (platform: string, action: string, additionalData?: TrackingEventData): void => {\r\n trackEvent('Social', 'click', platform, undefined, {\r\n social_platform: platform,\r\n social_action: action,\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// FAQ\r\n// ====================================\r\n\r\nexport const trackFAQExpand = (question: string, index: number): void => {\r\n trackEvent('FAQ', 'expand', question, index, {\r\n question,\r\n question_index: index,\r\n });\r\n};\r\n\r\n// ====================================\r\n// ENGAGEMENT\r\n// ====================================\r\n\r\nexport const trackImageClick = (imageName: string, section: string): void => {\r\n trackEvent('Engagement', 'image_click', imageName, undefined, {\r\n image_name: imageName,\r\n section,\r\n });\r\n};\r\n\r\nexport const trackTimeInSection = (sectionName: string, seconds: number): void => {\r\n if (seconds < 3) return; // Ignorar secciones vistas menos de 3 segundos\r\n\r\n trackEvent('Engagement', 'time_in_section', sectionName, Math.round(seconds), {\r\n section_name: sectionName,\r\n time_seconds: Math.round(seconds),\r\n });\r\n};\r\n\r\n// ====================================\r\n// NAVEGACIÓN\r\n// ====================================\r\n\r\nexport const trackSectionClick = (section: string): void => {\r\n trackEvent('Navigation', 'section_click', section);\r\n};\r\n\r\nexport const trackScrollTo = (section: string): void => {\r\n trackEvent('Navigation', 'scroll_to', section);\r\n};\r\n\r\n// ====================================\r\n// PRICING\r\n// ====================================\r\n\r\nexport const trackPricingCardClick = (productName: string, price: number | string, additionalData?: TrackingEventData): void => {\r\n trackEvent('Pricing', 'card_click', productName, undefined, {\r\n product_name: productName,\r\n price: String(price),\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// CONTACTO\r\n// ====================================\r\n\r\nexport const trackContactClick = (method: string): void => {\r\n trackEvent('Contact', 'click', method, undefined, {\r\n contact_method: method,\r\n });\r\n};\r\n\r\n// ====================================\r\n// COMPARTIR\r\n// ====================================\r\n\r\nexport const trackShare = (platform: string, content: string): void => {\r\n trackEvent('Share', 'click', platform, undefined, {\r\n share_platform: platform,\r\n share_content: content,\r\n });\r\n};\r\n\r\n// ====================================\r\n// DESCARGAS\r\n// ====================================\r\n\r\nexport const trackDownload = (fileName: string, fileType: string): void => {\r\n trackEvent('Download', 'click', fileName, undefined, {\r\n file_name: fileName,\r\n file_type: fileType,\r\n });\r\n};\r\n","/**\r\n * Adaptador de video Wistia\r\n * Detecta automáticamente el SDK de Wistia y se enlaza a sus eventos.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { VideoStats, VideoUpdateCallback, VideoTrackerHandle } from '../core/types';\r\n\r\nconst createStats = (timeWatched: number, completed: boolean): VideoStats => ({\r\n timeWatched: Math.max(0, Math.round(timeWatched)),\r\n completed,\r\n lastUpdate: Date.now(),\r\n});\r\n\r\n/**\r\n * Inicia tracking de un video Wistia por su Media ID.\r\n * Detecta si el player es Wistia nativo o un <video> HTML5.\r\n * Retorna un handle con getStats(), onUpdate() y stop().\r\n *\r\n * @example\r\n * ```ts\r\n * const tracker = await trackWistiaByMediaId('abc123')\r\n * tracker.onUpdate((stats) => {\r\n * console.log(stats.timeWatched, stats.completed)\r\n * })\r\n * // Al desmontar:\r\n * tracker.stop()\r\n * ```\r\n */\r\nexport const trackWistiaByMediaId = async (mediaId: string): Promise<VideoTrackerHandle | null> => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n let stats: VideoStats = createStats(0, false);\r\n let updateCallbacks: VideoUpdateCallback[] = [];\r\n let stopped = false;\r\n\r\n const callUpdate = (): void => {\r\n updateCallbacks.forEach((cb) => cb(stats));\r\n };\r\n\r\n // --- Estrategia 1: Wistia SDK nativo via window._wq ---\r\n const bindWistiaSDK = (): boolean => {\r\n if (!window._wq) return false;\r\n\r\n window._wq.push({\r\n id: mediaId,\r\n onReady: (rawVideo: unknown) => {\r\n if (stopped) return;\r\n\r\n const video = rawVideo as {\r\n time: () => number;\r\n duration: () => number;\r\n percentWatched: () => number;\r\n bind: (event: string, cb: (...args: unknown[]) => void) => void;\r\n unbind: (event: string) => void;\r\n };\r\n\r\n const updateFromWistia = (): void => {\r\n const t = video.time();\r\n const d = video.duration();\r\n const pct = d > 0 ? Math.round((t / d) * 100) : 0;\r\n const isCompleted = stats.completed || pct >= 95;\r\n const newTime = Math.max(stats.timeWatched, Math.round(t));\r\n\r\n if (newTime !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTime, isCompleted);\r\n callUpdate();\r\n }\r\n };\r\n\r\n video.bind('play', updateFromWistia);\r\n video.bind('pause', updateFromWistia);\r\n video.bind('secondchange', updateFromWistia);\r\n video.bind('end', () => {\r\n stats = createStats(Math.round(video.duration()), true);\r\n callUpdate();\r\n });\r\n },\r\n });\r\n\r\n return true;\r\n };\r\n\r\n // --- Estrategia 2: <video> HTML5 fallback ---\r\n const bindHTML5Fallback = (): void => {\r\n const selector = `[data-wistia-id=\"${mediaId}\"], .wistia_embed[data-media-id=\"${mediaId}\"]`;\r\n const container = document.querySelector(selector);\r\n if (!container) return;\r\n\r\n const video = container.querySelector('video');\r\n if (!video) return;\r\n\r\n const onTimeUpdate = (): void => {\r\n if (stopped) return;\r\n const ct = Math.round(video.currentTime || 0);\r\n const dur = video.duration || 0;\r\n const pct = dur > 0 ? Math.round((ct / dur) * 100) : 0;\r\n const isCompleted = stats.completed || pct >= 95 || video.ended;\r\n const newTime = Math.max(stats.timeWatched, ct);\r\n\r\n if (newTime !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTime, isCompleted);\r\n callUpdate();\r\n }\r\n };\r\n\r\n const onEnded = (): void => {\r\n if (stopped) return;\r\n stats = createStats(Math.max(stats.timeWatched, Math.round(video.duration || 0)), true);\r\n callUpdate();\r\n };\r\n\r\n video.addEventListener('timeupdate', onTimeUpdate);\r\n video.addEventListener('ended', onEnded);\r\n };\r\n\r\n // Intentar ambas estrategias\r\n const wistiaReady = bindWistiaSDK();\r\n if (!wistiaReady) {\r\n // Esperar un poco e intentar con HTML5\r\n await new Promise<void>((resolve) => setTimeout(resolve, 2000));\r\n bindHTML5Fallback();\r\n }\r\n\r\n return {\r\n getStats: () => stats,\r\n onUpdate: (cb: VideoUpdateCallback) => {\r\n updateCallbacks.push(cb);\r\n return () => {\r\n updateCallbacks = updateCallbacks.filter((x) => x !== cb);\r\n };\r\n },\r\n stop: () => {\r\n stopped = true;\r\n updateCallbacks = [];\r\n },\r\n };\r\n};\r\n","/**\r\n * Adaptador de video Voomly\r\n * Usa 3 estrategias complementarias para trackear videos embebidos de Voomly.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { VideoStats, VideoUpdateCallback, VideoTrackerHandle } from '../core/types';\r\n\r\nconst createStats = (timeWatched: number, completed: boolean): VideoStats => ({\r\n timeWatched: Math.max(0, Math.round(timeWatched)),\r\n completed,\r\n lastUpdate: Date.now(),\r\n});\r\n\r\n/**\r\n * Busca recursivamente elementos <video> dentro de un root (document, shadow DOM, iframes).\r\n */\r\nconst findAllVideosInElement = (root: Element | Document | ShadowRoot): HTMLVideoElement[] => {\r\n const results: HTMLVideoElement[] = [];\r\n\r\n // Buscar videos directos\r\n const videos = Array.from(root.querySelectorAll('video')) as HTMLVideoElement[];\r\n results.push(...videos);\r\n\r\n // Buscar en Shadow DOM\r\n const allElements = root.querySelectorAll('*');\r\n for (const el of Array.from(allElements)) {\r\n if (el.shadowRoot) {\r\n results.push(...findAllVideosInElement(el.shadowRoot));\r\n }\r\n }\r\n\r\n // Buscar en iframes (solo same-origin)\r\n const iframes = root.querySelectorAll('iframe');\r\n for (const iframe of Array.from(iframes)) {\r\n try {\r\n const doc = iframe.contentDocument || iframe.contentWindow?.document;\r\n if (doc) {\r\n results.push(...findAllVideosInElement(doc));\r\n }\r\n } catch {\r\n // Ignorar iframes bloqueados por CORS\r\n }\r\n }\r\n\r\n return results;\r\n};\r\n\r\n/**\r\n * Inicia tracking de un video Voomly por su Embed ID.\r\n * Usa 3 estrategias complementarias:\r\n * 1. Scan periódico del DOM (cada 2s) buscando <video> dentro del embed\r\n * 2. Polling de respaldo (cada 1s) leyendo .currentTime\r\n * 3. Eventos globales de window (voomly:video:*)\r\n *\r\n * @example\r\n * ```ts\r\n * const tracker = await trackVoomlyByEmbedId('my-voomly-id')\r\n * tracker.onUpdate((stats) => console.log(stats))\r\n * // IMPORTANTE: llamar stop() al desmontar para evitar memory leaks\r\n * tracker.stop()\r\n * ```\r\n */\r\nexport const trackVoomlyByEmbedId = async (embedId: string): Promise<VideoTrackerHandle | null> => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n let stats: VideoStats = createStats(0, false);\r\n let updateCallbacks: VideoUpdateCallback[] = [];\r\n const trackedVideos = new Set<HTMLVideoElement>();\r\n\r\n const callUpdate = (): void => {\r\n updateCallbacks.forEach((cb) => cb(stats));\r\n };\r\n\r\n const updateStatsFromVideo = (video: HTMLVideoElement): void => {\r\n const ct = Math.round(video.currentTime || 0);\r\n const dur = video.duration || 0;\r\n const pct = dur ? Math.round((ct / dur) * 100) : 0;\r\n\r\n const isCompleted = stats.completed || pct >= 90 || video.ended;\r\n const newTimeWatched = Math.max(stats.timeWatched, ct);\r\n\r\n if (newTimeWatched !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTimeWatched, isCompleted);\r\n callUpdate();\r\n }\r\n };\r\n\r\n // --- Event handlers para <video> HTML5 ---\r\n const onPlay = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n const onPause = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n const onTime = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n const onEnd = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n\r\n const bindVideo = (video: HTMLVideoElement): void => {\r\n if (trackedVideos.has(video)) return;\r\n trackedVideos.add(video);\r\n\r\n video.addEventListener('play', onPlay);\r\n video.addEventListener('pause', onPause);\r\n video.addEventListener('timeupdate', onTime);\r\n video.addEventListener('ended', onEnd);\r\n };\r\n\r\n // --- Estrategia 1: Scan periódico del DOM ---\r\n const scanForVideos = (): void => {\r\n const selector = `.voomly-embed[data-id=\"${embedId}\"]`;\r\n const container = document.querySelector(selector);\r\n\r\n let foundVideos: HTMLVideoElement[] = [];\r\n\r\n if (container) {\r\n foundVideos = findAllVideosInElement(container);\r\n }\r\n\r\n // Fallback: buscar en todo el document si no hay en el container\r\n if (foundVideos.length === 0) {\r\n foundVideos = findAllVideosInElement(document);\r\n }\r\n\r\n foundVideos.forEach((v) => bindVideo(v));\r\n };\r\n\r\n scanForVideos();\r\n const scanInterval = setInterval(scanForVideos, 2000);\r\n\r\n // --- Estrategia 2: Polling de respaldo ---\r\n const pollingInterval = setInterval(() => {\r\n trackedVideos.forEach((video) => {\r\n const ct = Math.round(video.currentTime || 0);\r\n if (!video.paused || ct > 0) {\r\n updateStatsFromVideo(video);\r\n }\r\n });\r\n }, 1000);\r\n\r\n // --- Estrategia 3: Eventos globales de Voomly API ---\r\n const handleVoomlyWindowEvents = (e: Event): void => {\r\n try {\r\n const customEvent = e as CustomEvent;\r\n const payload = customEvent.detail || (customEvent as unknown as { payload: unknown }).payload;\r\n const playerInfo = (payload as Record<string, unknown>)?.playerInfo || payload;\r\n const id = (playerInfo as Record<string, unknown>)?.id || (playerInfo as Record<string, unknown>)?.videoId;\r\n\r\n // Si el evento tiene un ID y no coincide, ignorar\r\n if (id && id !== embedId) return;\r\n\r\n const currentTime =\r\n ((payload as Record<string, unknown>)?.currentTime as number) || ((payload as Record<string, unknown>)?.time as number) || 0;\r\n const duration =\r\n ((payload as Record<string, unknown>)?.duration as number) || ((payload as Record<string, unknown>)?.totalTime as number) || 0;\r\n let completed = false;\r\n\r\n if (e.type === 'voomly:video:ended' || e.type === 'voomly:video:complete') {\r\n completed = true;\r\n }\r\n\r\n if (currentTime > 0 || completed) {\r\n const pct = duration ? Math.round((currentTime / duration) * 100) : 0;\r\n const isCompleted = stats.completed || completed || pct >= 90;\r\n const newTimeWatched = Math.max(stats.timeWatched, Math.round(currentTime));\r\n\r\n if (newTimeWatched !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTimeWatched, isCompleted);\r\n callUpdate();\r\n }\r\n }\r\n } catch {\r\n // ignore parsing errors\r\n }\r\n };\r\n\r\n const windowEvents = ['voomly:video:play', 'voomly:video:timeupdate', 'voomly:video:ended', 'voomly:video:progress'];\r\n windowEvents.forEach((evt) => window.addEventListener(evt, handleVoomlyWindowEvents));\r\n\r\n // --- Stop / cleanup ---\r\n const stop = (): void => {\r\n clearInterval(scanInterval);\r\n clearInterval(pollingInterval);\r\n trackedVideos.forEach((video) => {\r\n video.removeEventListener('play', onPlay);\r\n video.removeEventListener('pause', onPause);\r\n video.removeEventListener('timeupdate', onTime);\r\n video.removeEventListener('ended', onEnd);\r\n });\r\n windowEvents.forEach((evt) => window.removeEventListener(evt, handleVoomlyWindowEvents));\r\n updateCallbacks = [];\r\n };\r\n\r\n return {\r\n getStats: () => stats,\r\n onUpdate: (cb: VideoUpdateCallback) => {\r\n updateCallbacks.push(cb);\r\n return () => {\r\n updateCallbacks = updateCallbacks.filter((x) => x !== cb);\r\n };\r\n },\r\n stop,\r\n };\r\n};\r\n","/**\r\n * Adaptador de video HTML5 nativo\r\n * Tracking puro de elementos <video> sin dependencia de React.\r\n */\r\n\r\nimport type { VideoStats, VideoUpdateCallback, VideoTrackerHandle } from '../core/types';\r\n\r\nconst createStats = (timeWatched: number, completed: boolean): VideoStats => ({\r\n timeWatched: Math.max(0, Math.round(timeWatched)),\r\n completed,\r\n lastUpdate: Date.now(),\r\n});\r\n\r\n/**\r\n * Inicia tracking de un elemento <video> HTML5 nativo.\r\n * Escucha eventos estándar del Video API del navegador.\r\n *\r\n * @example\r\n * ```ts\r\n * const video = document.querySelector('video')\r\n * const tracker = trackHTML5Video('hero-video', video)\r\n * tracker.onUpdate((stats) => console.log(stats))\r\n * // Al desmontar:\r\n * tracker.stop()\r\n * ```\r\n */\r\nexport const trackHTML5Video = (videoId: string, videoElement: HTMLVideoElement): VideoTrackerHandle => {\r\n let stats: VideoStats = createStats(0, false);\r\n let updateCallbacks: VideoUpdateCallback[] = [];\r\n const trackedMilestones = new Set<number>();\r\n\r\n const callUpdate = (): void => {\r\n updateCallbacks.forEach((cb) => cb(stats));\r\n };\r\n\r\n const onTimeUpdate = (): void => {\r\n const ct = Math.round(videoElement.currentTime || 0);\r\n const dur = videoElement.duration || 0;\r\n const pct = dur > 0 ? Math.round((ct / dur) * 100) : 0;\r\n\r\n // Actualizar stats\r\n const newTime = Math.max(stats.timeWatched, ct);\r\n const isCompleted = stats.completed || pct >= 95 || videoElement.ended;\r\n\r\n if (newTime !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTime, isCompleted);\r\n callUpdate();\r\n }\r\n\r\n // Milestones (25, 50, 75)\r\n for (const milestone of [25, 50, 75]) {\r\n if (pct >= milestone && !trackedMilestones.has(milestone)) {\r\n trackedMilestones.add(milestone);\r\n }\r\n }\r\n };\r\n\r\n const onEnded = (): void => {\r\n const dur = Math.round(videoElement.duration || 0);\r\n stats = createStats(Math.max(stats.timeWatched, dur), true);\r\n callUpdate();\r\n };\r\n\r\n const onPlay = (): void => {\r\n onTimeUpdate();\r\n };\r\n\r\n const onPause = (): void => {\r\n onTimeUpdate();\r\n };\r\n\r\n // Bind events\r\n videoElement.addEventListener('timeupdate', onTimeUpdate);\r\n videoElement.addEventListener('ended', onEnded);\r\n videoElement.addEventListener('play', onPlay);\r\n videoElement.addEventListener('pause', onPause);\r\n\r\n return {\r\n getStats: () => stats,\r\n onUpdate: (cb: VideoUpdateCallback) => {\r\n updateCallbacks.push(cb);\r\n return () => {\r\n updateCallbacks = updateCallbacks.filter((x) => x !== cb);\r\n };\r\n },\r\n stop: () => {\r\n videoElement.removeEventListener('timeupdate', onTimeUpdate);\r\n videoElement.removeEventListener('ended', onEnded);\r\n videoElement.removeEventListener('play', onPlay);\r\n videoElement.removeEventListener('pause', onPause);\r\n updateCallbacks = [];\r\n },\r\n };\r\n};\r\n","/**\r\n * LandingTracker — Orquestador de sesión completa\r\n * Inicializa y gestiona scroll tracking, click heatmap, section dwell time,\r\n * form auto-tracking y sesión start/end.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport { trackEvent, captureUTMParams, captureUserIdFromURL, getUserName, trackPageView } from '../core/analytics';\r\nimport { pushToDataLayer, injectGTMScript } from '../core/gtm';\r\nimport { trackCTAClick, trackFormStart, trackFormSubmit, trackTimeInSection } from '../trackers/events';\r\nimport type { LandingTrackerConfig, ClickData } from '../core/types';\r\n\r\nexport class LandingTracker {\r\n private config: LandingTrackerConfig | null = null;\r\n private isInitialized = false;\r\n private sessionStartTime: number = 0;\r\n private scrollMilestonesReached = new Set<number>();\r\n private clicks: ClickData[] = [];\r\n private sectionTimers: Map<string, number> = new Map();\r\n private observers: IntersectionObserver[] = [];\r\n private listeners: Array<{ target: EventTarget; event: string; handler: EventListener }> = [];\r\n\r\n /**\r\n * Inicializa el tracking de la landing con la configuración dada.\r\n */\r\n init(config: LandingTrackerConfig): void {\r\n if (typeof window === 'undefined') return;\r\n if (this.isInitialized) return;\r\n\r\n this.config = {\r\n enableScrollTracking: true,\r\n enableCTATracking: true,\r\n enableTimeTracking: true,\r\n enableSectionTracking: true,\r\n enableFormTracking: true,\r\n enableHeatmap: false,\r\n eventSuffix: '',\r\n ...config,\r\n };\r\n\r\n this.isInitialized = true;\r\n this.sessionStartTime = Date.now();\r\n\r\n // Capturar datos iniciales del visitante\r\n this.captureInitialData();\r\n\r\n // Trackear carga de página\r\n trackPageView(this.config.pagePath);\r\n\r\n // Inyectar GTM si se proporcionó\r\n if (this.config.gtmId) {\r\n injectGTMScript(this.config.gtmId);\r\n pushToDataLayer(this.getEventName('page_load'), {\r\n page_path: this.config.pagePath,\r\n page_title: this.config.pageName,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n // Inicializar módulos de tracking\r\n if (this.config.enableScrollTracking) this.initScrollTracking();\r\n if (this.config.enableCTATracking) this.initCTATracking();\r\n if (this.config.enableTimeTracking) this.initTimeTracking();\r\n if (this.config.enableSectionTracking) this.initSectionTracking();\r\n if (this.config.enableFormTracking) this.initFormTracking();\r\n if (this.config.enableHeatmap) this.initClickHeatmap();\r\n\r\n // Trackear inicio de sesión\r\n this.trackSessionStart();\r\n }\r\n\r\n /**\r\n * Destruye el tracker y limpia todos los observers y listeners.\r\n */\r\n destroy(): void {\r\n // Cleanup observers\r\n this.observers.forEach((obs) => obs.disconnect());\r\n this.observers = [];\r\n\r\n // Cleanup event listeners\r\n this.listeners.forEach(({ target, event, handler }) => {\r\n target.removeEventListener(event, handler);\r\n });\r\n this.listeners = [];\r\n\r\n this.isInitialized = false;\r\n this.config = null;\r\n this.scrollMilestonesReached.clear();\r\n this.clicks = [];\r\n this.sectionTimers.clear();\r\n }\r\n\r\n // ====================================\r\n // MÉTODOS PÚBLICOS DE TRACKING\r\n // ====================================\r\n\r\n /** Trackear click en un CTA */\r\n trackCTAClick(buttonName: string, section: string, additionalData?: Record<string, unknown>): void {\r\n trackCTAClick(buttonName, section, additionalData);\r\n this.pushGTMEvent('cta_click', { button_text: buttonName, section });\r\n }\r\n\r\n /** Trackear conversión */\r\n trackConversion(type: string, value?: number, additionalData?: Record<string, unknown>): void {\r\n trackEvent('Conversion', type, undefined, value, additionalData);\r\n this.pushGTMEvent('conversion', { conversion_type: type, value });\r\n }\r\n\r\n /** Trackear click en FAQs */\r\n trackFAQExpand(question: string, index: number): void {\r\n trackEvent('FAQ', 'expand', question, index);\r\n }\r\n\r\n /** Trackear click social */\r\n trackSocialClick(platform: string, action: string): void {\r\n trackEvent('Social', 'click', platform, undefined, { social_action: action });\r\n }\r\n\r\n /** Trackear click en imagen */\r\n trackImageClick(imageName: string, section: string): void {\r\n trackEvent('Engagement', 'image_click', imageName, undefined, { section });\r\n }\r\n\r\n /** Trackear scroll a sección */\r\n trackScrollTo(section: string): void {\r\n trackEvent('Navigation', 'scroll_to', section);\r\n }\r\n\r\n /** Trackear share */\r\n trackShare(platform: string, content: string): void {\r\n trackEvent('Share', 'click', platform, undefined, { share_content: content });\r\n }\r\n\r\n /** Trackear descarga */\r\n trackDownload(fileName: string, fileType: string): void {\r\n trackEvent('Download', 'click', fileName, undefined, { file_type: fileType });\r\n }\r\n\r\n /** Obtener datos de la sesión actual */\r\n getSessionData(): { duration: number; clicks: number; scrollMilestones: number[] } {\r\n return {\r\n duration: Math.round((Date.now() - this.sessionStartTime) / 1000),\r\n clicks: this.clicks.length,\r\n scrollMilestones: Array.from(this.scrollMilestonesReached),\r\n };\r\n }\r\n\r\n // ====================================\r\n // MÉTODOS PRIVADOS\r\n // ====================================\r\n\r\n private captureInitialData(): void {\r\n const utmParams = captureUTMParams();\r\n const userId = captureUserIdFromURL();\r\n const userName = getUserName();\r\n\r\n const prefix = this.config!.pagePath.replace('/', '');\r\n\r\n try {\r\n localStorage.setItem(`${prefix}_entry_time`, new Date().toISOString());\r\n if (utmParams) {\r\n localStorage.setItem(`${prefix}_utm_params`, JSON.stringify(utmParams));\r\n }\r\n if (userId) {\r\n localStorage.setItem(`${prefix}_user_id`, userId);\r\n }\r\n } catch {\r\n // localStorage puede no estar disponible\r\n }\r\n\r\n // Enviar evento de carga\r\n trackEvent('Landing', 'page_load', this.config!.pageName, undefined, {\r\n page_path: this.config!.pagePath,\r\n user_id: userId,\r\n user_name: userName,\r\n utm_params: utmParams,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n private trackSessionStart(): void {\r\n trackEvent('Session', 'start', this.config!.pageName, undefined, {\r\n page_path: this.config!.pagePath,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n private getEventName(baseName: string): string {\r\n const suffix = this.config?.eventSuffix || '';\r\n return suffix ? `${baseName}${suffix}` : baseName;\r\n }\r\n\r\n private pushGTMEvent(eventName: string, data?: Record<string, unknown>): void {\r\n if (this.config?.gtmId) {\r\n pushToDataLayer(this.getEventName(eventName), {\r\n page_path: this.config.pagePath,\r\n ...data,\r\n });\r\n }\r\n }\r\n\r\n private addListener(target: EventTarget, event: string, handler: EventListener): void {\r\n target.addEventListener(event, handler);\r\n this.listeners.push({ target, event, handler });\r\n }\r\n\r\n // --- Scroll Tracking ---\r\n private initScrollTracking(): void {\r\n let scrollTimeout: ReturnType<typeof setTimeout>;\r\n\r\n const handler = (): void => {\r\n clearTimeout(scrollTimeout);\r\n scrollTimeout = setTimeout(() => {\r\n const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;\r\n if (scrollHeight <= 0) return;\r\n\r\n const pct = Math.round((window.scrollY / scrollHeight) * 100);\r\n\r\n for (const milestone of [25, 50, 75, 100]) {\r\n if (pct >= milestone && !this.scrollMilestonesReached.has(milestone)) {\r\n this.scrollMilestonesReached.add(milestone);\r\n\r\n trackEvent('Scroll', 'milestone', `${milestone}%`, milestone, {\r\n page_path: this.config!.pagePath,\r\n scroll_percentage: milestone,\r\n });\r\n\r\n this.pushGTMEvent('scroll_milestone', { scroll_percentage: milestone });\r\n }\r\n }\r\n }, 100);\r\n };\r\n\r\n this.addListener(window, 'scroll', handler as EventListener);\r\n }\r\n\r\n // --- CTA Tracking ---\r\n private initCTATracking(): void {\r\n setTimeout(() => {\r\n const ctaButtons = document.querySelectorAll('button, a[href*=\"#\"], [data-cta]');\r\n ctaButtons.forEach((button) => {\r\n const handler = (): void => {\r\n const el = button as HTMLElement;\r\n const text = el.textContent?.trim() || el.getAttribute('data-cta') || 'Unknown CTA';\r\n const section = el.closest('section')?.id || el.closest('[data-section]')?.getAttribute('data-section') || 'unknown';\r\n\r\n this.trackCTAClick(text, section);\r\n };\r\n this.addListener(button, 'click', handler as EventListener);\r\n });\r\n }, 2000); // Esperar a que el DOM esté completo\r\n }\r\n\r\n // --- Time Tracking (page exit) ---\r\n private initTimeTracking(): void {\r\n const handler = (): void => {\r\n const duration = Math.round((Date.now() - this.sessionStartTime) / 1000);\r\n\r\n trackEvent('Session', 'end', this.config!.pageName, duration, {\r\n session_duration: duration,\r\n page_path: this.config!.pagePath,\r\n exit_timestamp: Date.now(),\r\n });\r\n\r\n this.pushGTMEvent('page_exit', {\r\n session_duration: duration,\r\n exit_timestamp: Date.now(),\r\n });\r\n };\r\n\r\n this.addListener(window, 'beforeunload', handler as EventListener);\r\n }\r\n\r\n // --- Section Dwell Time (IntersectionObserver) ---\r\n private initSectionTracking(): void {\r\n const sectionEntryTimes = new Map<string, number>();\r\n\r\n const observer = new IntersectionObserver(\r\n (entries) => {\r\n entries.forEach((entry) => {\r\n const sectionId = (entry.target as HTMLElement).id || (entry.target as HTMLElement).getAttribute('data-section') || 'unknown';\r\n\r\n if (entry.isIntersecting) {\r\n sectionEntryTimes.set(sectionId, Date.now());\r\n } else {\r\n const entryTime = sectionEntryTimes.get(sectionId);\r\n if (entryTime) {\r\n const seconds = (Date.now() - entryTime) / 1000;\r\n trackTimeInSection(sectionId, seconds);\r\n sectionEntryTimes.delete(sectionId);\r\n }\r\n }\r\n });\r\n },\r\n { threshold: 0.5 },\r\n );\r\n\r\n // Observar todas las secciones\r\n setTimeout(() => {\r\n const sections = document.querySelectorAll('section, [data-section]');\r\n sections.forEach((section) => observer.observe(section));\r\n }, 1000);\r\n\r\n this.observers.push(observer);\r\n }\r\n\r\n // --- Form Auto-Tracking ---\r\n private initFormTracking(): void {\r\n setTimeout(() => {\r\n const forms = document.querySelectorAll('form');\r\n forms.forEach((form) => {\r\n const formName = form.getAttribute('name') || form.id || 'unknown-form';\r\n\r\n // Track form focus (start)\r\n let started = false;\r\n const inputs = form.querySelectorAll('input, textarea, select');\r\n inputs.forEach((input) => {\r\n this.addListener(input, 'focus', (() => {\r\n if (!started) {\r\n started = true;\r\n trackFormStart(formName);\r\n }\r\n }) as EventListener);\r\n });\r\n\r\n // Track form submit\r\n this.addListener(form, 'submit', ((_e: Event) => {\r\n trackFormSubmit(formName, true, {\r\n page_path: this.config!.pagePath,\r\n });\r\n this.pushGTMEvent('form_submit', { form_name: formName });\r\n }) as EventListener);\r\n });\r\n }, 2000);\r\n }\r\n\r\n // --- Click Heatmap ---\r\n private initClickHeatmap(): void {\r\n const handler = (e: Event): void => {\r\n const mouseEvent = e as MouseEvent;\r\n const target = mouseEvent.target as HTMLElement;\r\n\r\n const clickData: ClickData = {\r\n x: mouseEvent.clientX,\r\n y: mouseEvent.clientY,\r\n element: target.tagName.toLowerCase(),\r\n section: target.closest('section')?.id || 'unknown',\r\n timestamp: Date.now(),\r\n viewportWidth: window.innerWidth,\r\n viewportHeight: window.innerHeight,\r\n };\r\n\r\n this.clicks.push(clickData);\r\n };\r\n\r\n this.addListener(document, 'click', handler as EventListener);\r\n }\r\n}\r\n\r\n/**\r\n * Factory function para crear un LandingTracker.\r\n *\r\n * @example\r\n * ```ts\r\n * const tracker = createLandingTracker({\r\n * pagePath: '/kin',\r\n * pageName: 'Kin Landing Page',\r\n * gtmId: 'GTM-5GMQNFMN',\r\n * })\r\n * // Al desmontar:\r\n * tracker.destroy()\r\n * ```\r\n */\r\nexport const createLandingTracker = (config: LandingTrackerConfig): LandingTracker => {\r\n const tracker = new LandingTracker();\r\n tracker.init(config);\r\n return tracker;\r\n};\r\n","/**\r\n * API Client — Cliente HTTP configurable para persistencia al backend.\r\n * Framework-agnostic. Usa fetch nativo.\r\n *\r\n * @example\r\n * ```ts\r\n * import { initTrackingAPI } from '@metodokorexmk/tracking';\r\n *\r\n * initTrackingAPI({\r\n * baseUrl: 'https://api.korex.com/api/v1',\r\n * getAuthToken: () => localStorage.getItem('access_token'),\r\n * });\r\n * ```\r\n */\r\n\r\nimport type { TrackingAPIConfig } from '../core/types';\r\n\r\nlet apiConfig: TrackingAPIConfig | null = null;\r\n\r\n/**\r\n * Inicializa el cliente HTTP para la capa de persistencia.\r\n * Debe llamarse antes de usar funciones de lead submission, dwell time o queries.\r\n */\r\nexport const initTrackingAPI = (config: TrackingAPIConfig): void => {\r\n apiConfig = {\r\n ...config,\r\n baseUrl: config.baseUrl.replace(/\\/+$/, ''),\r\n };\r\n};\r\n\r\n/**\r\n * Retorna la config actual. Lanza error si no se ha inicializado.\r\n */\r\nexport const getAPIConfig = (): TrackingAPIConfig => {\r\n if (!apiConfig) {\r\n throw new Error('[@metodokorexmk/tracking] initTrackingAPI() debe llamarse antes de usar funciones de persistencia.');\r\n }\r\n return apiConfig;\r\n};\r\n\r\n/**\r\n * Verifica si el API client ha sido inicializado.\r\n */\r\nexport const isTrackingAPIInitialized = (): boolean => apiConfig !== null;\r\n\r\n/**\r\n * Construye los headers de la petición, incluyendo auth token si está disponible.\r\n */\r\nconst buildHeaders = (): HeadersInit => {\r\n const config = getAPIConfig();\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (config.getAuthToken) {\r\n const token = config.getAuthToken();\r\n if (token) {\r\n headers.Authorization = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n if (config.getCustomHeaders) {\r\n Object.assign(headers, config.getCustomHeaders());\r\n }\r\n\r\n return headers;\r\n};\r\n\r\n/**\r\n * GET request al API.\r\n */\r\nexport const apiGet = async <T>(path: string): Promise<T> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: buildHeaders(),\r\n credentials: 'include',\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => '');\r\n throw new Error(`API GET ${path} failed (${response.status}): ${errorText}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n};\r\n\r\n/**\r\n * POST request al API.\r\n */\r\nexport const apiPost = async <T>(path: string, body: Record<string, unknown>): Promise<T> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: buildHeaders(),\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => '');\r\n throw new Error(`API POST ${path} failed (${response.status}): ${errorText}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n};\r\n\r\n/**\r\n * PATCH request al API con soporte para keepalive (útil en beforeunload).\r\n */\r\nexport const apiPatch = async <T>(\r\n path: string,\r\n body: Record<string, unknown>,\r\n options?: { keepalive?: boolean; timeoutMs?: number },\r\n): Promise<T> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n const controller = new AbortController();\r\n\r\n const timeoutMs = options?.timeoutMs ?? 10000;\r\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: buildHeaders(),\r\n body: JSON.stringify(body),\r\n keepalive: options?.keepalive ?? false,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => '');\r\n throw new Error(`API PATCH ${path} failed (${response.status}): ${errorText}`);\r\n }\r\n\r\n // Intentar parsear JSON, si falla retornar objeto vacío\r\n const text = await response.text();\r\n try {\r\n return JSON.parse(text) as T;\r\n } catch {\r\n return {} as T;\r\n }\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * PATCH request usando fetch con keepalive (para beforeunload).\r\n * No espera respuesta. Fire-and-forget.\r\n */\r\nexport const apiPatchFireAndForget = (path: string, body: Record<string, unknown>): void => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (config.getAuthToken) {\r\n const token = config.getAuthToken();\r\n if (token) {\r\n headers.Authorization = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n // Fire-and-forget con keepalive\r\n fetch(url, {\r\n method: 'PATCH',\r\n headers,\r\n body: JSON.stringify(body),\r\n keepalive: true,\r\n }).catch(() => {\r\n // Ignorar errores en fire-and-forget\r\n });\r\n};\r\n","/**\r\n * Lead Submission — Creación y actualización de leads en el backend.\r\n * Migrado de lead-origin-detector.ts, framework-agnostic.\r\n */\r\n\r\nimport type {\r\n UrlParams,\r\n LeadOrigin,\r\n LeadFormData,\r\n TrackingLeadResponse,\r\n SubmitTrackingLeadResponse,\r\n BuildRequestBodyOptions,\r\n} from '../core/types';\r\nimport { getAPIConfig } from './api-client';\r\n\r\n// ====================================\r\n// URL PARAMS\r\n// ====================================\r\n\r\n/**\r\n * Extrae todos los parámetros relevantes de la URL.\r\n *\r\n * @param url - URL opcional (si no se proporciona, usa window.location)\r\n * @returns Objeto con todos los parámetros extraídos\r\n */\r\nexport const extractUrlParams = (url?: string): UrlParams => {\r\n if (typeof window === 'undefined' && !url) {\r\n return {\r\n userId: '',\r\n idCampana: '',\r\n utmContent: '',\r\n fbclid: '',\r\n nombreNetworker: '',\r\n whatsapp: '',\r\n pipelineId: '',\r\n leadCampaing: 'Funnel Organico',\r\n isOrganico: true,\r\n };\r\n }\r\n\r\n let searchParams: URLSearchParams;\r\n if (url) {\r\n try {\r\n const urlObj = new URL(url);\r\n searchParams = new URLSearchParams(urlObj.search);\r\n } catch {\r\n searchParams = new URLSearchParams();\r\n }\r\n } else {\r\n searchParams = new URLSearchParams(window.location.search);\r\n }\r\n\r\n const userId = searchParams.get('user_id') || '';\r\n const idCampana = searchParams.get('campaign_id') || searchParams.get('utm_id') || '';\r\n const utmContent = searchParams.get('utm_content') || '';\r\n const fbclid = searchParams.get('fbclid') || '';\r\n const whatsapp = searchParams.get('whatsapp') || '';\r\n const nombreNetworker = searchParams.get('user_name') || searchParams.get('networker') || searchParams.get('name') || '';\r\n const pipelineId = searchParams.get('pipeline_id') || '';\r\n const funnelId = searchParams.get('funnel_id') || '';\r\n const metricId = searchParams.get('metric_id') || '';\r\n const utmSource = searchParams.get('utm_source') || '';\r\n const utmMedium = searchParams.get('utm_medium') || '';\r\n const utmCampaign = searchParams.get('utm_campaign') || '';\r\n const isOrganico = !!(whatsapp && !idCampana && !fbclid);\r\n const leadCampaing = fbclid ? 'Funnel FB' : 'Funnel Organico';\r\n\r\n return {\r\n userId,\r\n idCampana,\r\n utmContent,\r\n fbclid,\r\n nombreNetworker,\r\n whatsapp,\r\n pipelineId,\r\n funnelId,\r\n metricId,\r\n utmSource,\r\n utmMedium,\r\n utmCampaign,\r\n leadCampaing,\r\n isOrganico,\r\n };\r\n};\r\n\r\n// ====================================\r\n// ORIGIN DETECTION\r\n// ====================================\r\n\r\n/**\r\n * Detecta el origen del lead basándose en los parámetros de la URL.\r\n * Facebook Ads: tiene fbclid O campaign_id\r\n * Orgánico: tiene whatsapp Y NO tiene fbclid Y NO tiene campaign_id\r\n */\r\nexport const detectLeadOrigin = (url?: string): LeadOrigin => {\r\n const params = extractUrlParams(url);\r\n const hasCampaign = Boolean(params.idCampana || params.fbclid);\r\n const type: 'facebook' | 'organic' = hasCampaign ? 'facebook' : 'organic';\r\n\r\n const endpoint = hasCampaign ? '/tracking/create-with-lead-and-distribution' : '/tracking/create-organic-lead';\r\n\r\n return { type, endpoint, params, hasCampaign };\r\n};\r\n\r\n// ====================================\r\n// BODY BUILDER\r\n// ====================================\r\n\r\n/**\r\n * Construye el body de la petición según el tipo de origen.\r\n */\r\nexport const buildTrackingRequestBody = (\r\n params: UrlParams,\r\n formData: LeadFormData,\r\n origin: LeadOrigin,\r\n options?: BuildRequestBodyOptions,\r\n): Record<string, unknown> => {\r\n const collaboratorId = params.userId ? parseInt(params.userId, 10) : null;\r\n const telefonoLimpio = formData.telefono.replace(/\\s+/g, '');\r\n\r\n const body: Record<string, unknown> = {\r\n userName: formData.nombre.trim(),\r\n userEmail: formData.correo.trim(),\r\n entryDate: new Date().toISOString(),\r\n accessUrl: typeof window !== 'undefined' ? window.location.href : '',\r\n leadName: formData.nombre.trim(),\r\n leadEmail: formData.correo.trim(),\r\n leadPhone: formData.countryLada ? `${formData.countryLada}${telefonoLimpio}` : telefonoLimpio,\r\n };\r\n\r\n // Campos opcionales\r\n if (options?.nameForm) body.nameForm = options.nameForm;\r\n if (options?.msgForm) body.msgForm = options.msgForm;\r\n if (options?.status) body.status = options.status;\r\n if (options?.whatsappSent !== undefined) body.whatsapp_sent = options.whatsappSent;\r\n if (options?.dwellTime !== undefined) body.dwellTime = options.dwellTime;\r\n if (options?.videoTimeWatched !== undefined) body.videoTimeWatched = options.videoTimeWatched;\r\n if (options?.videoCompleted !== undefined) {\r\n body.videoCompleted = options.videoCompleted;\r\n body.video_completed = options.videoCompleted;\r\n }\r\n\r\n // Campos según tipo de origen\r\n if (origin.hasCampaign) {\r\n if (collaboratorId) body.userId = collaboratorId;\r\n if (params.idCampana) body.idCampana = params.idCampana;\r\n if (params.utmContent) body.utmContent = params.utmContent;\r\n if (params.fbclid) body.fbclid = params.fbclid;\r\n } else if (collaboratorId) {\r\n body.referringUserId = collaboratorId;\r\n body.referring_user_id = collaboratorId;\r\n }\r\n\r\n // Pipeline, funnel, metric IDs\r\n if (params.pipelineId) {\r\n const parsed = parseInt(params.pipelineId, 10);\r\n if (!isNaN(parsed)) body.pipeline_id = parsed;\r\n }\r\n if (params.funnelId) {\r\n const parsed = parseInt(params.funnelId, 10);\r\n if (!isNaN(parsed)) body.funnel_id = parsed;\r\n }\r\n if (params.metricId) {\r\n const parsed = parseInt(params.metricId, 10);\r\n if (!isNaN(parsed)) body.metric_id = parsed;\r\n }\r\n\r\n // Campos adicionales\r\n if (options?.additionalFields) {\r\n Object.assign(body, options.additionalFields);\r\n }\r\n\r\n return body;\r\n};\r\n\r\n// ====================================\r\n// SUBMIT / UPDATE\r\n// ====================================\r\n\r\n/**\r\n * Envía el lead al endpoint correcto según su origen.\r\n */\r\nexport const submitTrackingLead = async (body: Record<string, unknown>, origin: LeadOrigin): Promise<SubmitTrackingLeadResponse> => {\r\n const config = getAPIConfig();\r\n const fullUrl = `${config.baseUrl}${origin.endpoint}`;\r\n\r\n try {\r\n const response = await fetch(fullUrl, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n });\r\n\r\n let data: TrackingLeadResponse | null = null;\r\n try {\r\n const text = await response.text();\r\n if (text) {\r\n const parsed = JSON.parse(text);\r\n if (parsed && typeof parsed === 'object') {\r\n data = parsed as TrackingLeadResponse;\r\n }\r\n }\r\n } catch {\r\n // Error de parsing, data queda null\r\n }\r\n\r\n return { ok: response.ok, status: response.status, data };\r\n } catch {\r\n return { ok: false, status: 0, data: null };\r\n }\r\n};\r\n\r\n/**\r\n * Función completa: detecta origen, construye body y envía el lead.\r\n *\r\n * @example\r\n * ```ts\r\n * const result = await submitLead(\r\n * { nombre: 'Juan', correo: 'juan@mail.com', telefono: '+34600...' },\r\n * { nameForm: 'Formulario Kin', videoCompleted: true },\r\n * );\r\n * ```\r\n */\r\nexport const submitLead = async (\r\n formData: LeadFormData,\r\n options?: BuildRequestBodyOptions,\r\n url?: string,\r\n): Promise<SubmitTrackingLeadResponse> => {\r\n const origin = detectLeadOrigin(url);\r\n const body = buildTrackingRequestBody(origin.params, formData, origin, options);\r\n return submitTrackingLead(body, origin);\r\n};\r\n\r\n/**\r\n * Actualiza un lead existente mediante PATCH.\r\n */\r\nexport const updateTrackingLead = async (trackingId: number | string, updates: Record<string, unknown>): Promise<boolean> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}/tracking/${trackingId}`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(updates),\r\n });\r\n return response.ok;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Marca un lead como \"WhatsApp enviado\".\r\n */\r\nexport const markWhatsAppSent = async (leadId: number | string): Promise<boolean> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}/tracking/lead/${leadId}/whatsapp-sent`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ whatsapp_sent: true }),\r\n });\r\n return response.ok;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Construye un msgForm como JSON stringificado.\r\n */\r\nexport const buildMsgFormJSON = (mensaje: string, datosAdicionales?: Record<string, unknown>): string => {\r\n return JSON.stringify({ mensaje: mensaje || '', ...datosAdicionales });\r\n};\r\n","/**\r\n * DwellTimeTracker — Tracking de tiempo de permanencia con envío periódico al backend.\r\n * Migrado de dwell-time.ts (~960 líneas → ~280 líneas limpias).\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { DwellTimeConfig } from '../core/types';\r\nimport { getAPIConfig, isTrackingAPIInitialized } from './api-client';\r\n\r\n/**\r\n * Clase que mide el tiempo de permanencia del usuario en una página\r\n * y lo envía periódicamente al backend de tracking.\r\n *\r\n * Características:\r\n * - Envío automático cada 30 segundos\r\n * - Pausa automática cuando la pestaña se oculta\r\n * - sendBeacon en beforeunload para máxima confiabilidad\r\n * - Retry de updates pendientes via sessionStorage\r\n * - Tracking de video integrado (videoTimeWatched, videoCompleted)\r\n */\r\nexport class DwellTimeTracker {\r\n private startTime: number | null = null;\r\n\r\n private trackingDataId: number | string | null = null;\r\n\r\n private enabled = false;\r\n\r\n private onSuccess?: () => void;\r\n\r\n private onError?: (error: Error) => void;\r\n\r\n private intervalId: ReturnType<typeof setInterval> | null = null;\r\n\r\n private isSending = false;\r\n\r\n private videoTimeWatched = 0;\r\n\r\n private videoCompleted = false;\r\n\r\n private videoTrackingStopped = false;\r\n\r\n private lastDwellTimeSent = 0;\r\n\r\n private lastVideoTimeSent = 0;\r\n\r\n private pausedTime = 0;\r\n\r\n private pauseStartTime: number | null = null;\r\n\r\n private boundBeforeUnload: (e: BeforeUnloadEvent) => void;\r\n\r\n private boundVisibilityChange: () => void;\r\n\r\n constructor() {\r\n this.boundBeforeUnload = this.handleBeforeUnload.bind(this);\r\n this.boundVisibilityChange = this.handleVisibilityChange.bind(this);\r\n }\r\n\r\n /**\r\n * Inicia el tracking del tiempo de permanencia.\r\n */\r\n start(config: DwellTimeConfig): void {\r\n if (typeof window === 'undefined') return;\r\n\r\n const wasAlreadyTracking = this.enabled;\r\n this.enabled = config.enabled !== false;\r\n this.trackingDataId = config.trackingDataId;\r\n this.onSuccess = config.onSuccess;\r\n this.onError = config.onError;\r\n\r\n if (!this.enabled) return;\r\n\r\n this.cleanupListeners();\r\n\r\n window.addEventListener('beforeunload', this.boundBeforeUnload);\r\n document.addEventListener('visibilitychange', this.boundVisibilityChange);\r\n\r\n if (!wasAlreadyTracking) {\r\n this.startTime = Date.now();\r\n }\r\n\r\n if (!this.intervalId) {\r\n this.intervalId = setInterval(() => {\r\n if (this.videoCompleted && this.videoTrackingStopped) {\r\n if (document.visibilityState === 'visible' && this.startTime) {\r\n this.sendDwellTime(false);\r\n }\r\n return;\r\n }\r\n\r\n if (this.videoCompleted && !this.videoTrackingStopped) {\r\n this.sendDwellTime(false);\r\n this.videoTrackingStopped = true;\r\n return;\r\n }\r\n\r\n if (document.visibilityState === 'visible' && this.startTime) {\r\n this.sendDwellTime(false);\r\n }\r\n }, 30000);\r\n }\r\n\r\n this.retryPendingUpdates();\r\n }\r\n\r\n /**\r\n * Detiene el tracking y envía el tiempo acumulado.\r\n */\r\n stop(): void {\r\n if (this.startTime) {\r\n this.sendDwellTime(true);\r\n }\r\n\r\n this.startTime = null;\r\n this.lastVideoTimeSent = 0;\r\n this.lastDwellTimeSent = 0;\r\n this.videoTrackingStopped = false;\r\n this.pausedTime = 0;\r\n this.pauseStartTime = null;\r\n this.cleanup();\r\n }\r\n\r\n /**\r\n * Obtiene el tiempo transcurrido en segundos (restando tiempo pausado).\r\n */\r\n getElapsedTime(): number {\r\n if (!this.startTime) return 0;\r\n\r\n const totalTime = Math.floor((Date.now() - this.startTime) / 1000);\r\n let currentPauseTime = this.pausedTime;\r\n\r\n if (this.pauseStartTime !== null) {\r\n currentPauseTime += Math.floor((Date.now() - this.pauseStartTime) / 1000);\r\n }\r\n\r\n return Math.max(0, totalTime - currentPauseTime);\r\n }\r\n\r\n /**\r\n * Actualiza manualmente el tiempo del video.\r\n * Llamar desde el VideoTracker u otros adaptadores.\r\n */\r\n updateVideoTime(videoTimeWatched: number, videoCompleted = false): void {\r\n const hasNewTime = videoTimeWatched > this.videoTimeWatched;\r\n const hasNewCompletion = videoCompleted && !this.videoCompleted;\r\n\r\n if (hasNewTime || hasNewCompletion) {\r\n this.videoTimeWatched = Math.max(this.videoTimeWatched, videoTimeWatched);\r\n this.videoCompleted = videoCompleted || this.videoCompleted;\r\n\r\n if (this.trackingDataId && this.trackingDataId !== 'pending' && this.startTime && hasNewCompletion) {\r\n this.sendDwellTime(false);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Actualiza el trackingDataId (útil cuando se obtiene después del registro).\r\n */\r\n updateTrackingId(trackingDataId: number | string): void {\r\n if (!trackingDataId || (typeof trackingDataId === 'string' && trackingDataId.trim() === '')) return;\r\n\r\n const oldTrackingId = this.trackingDataId;\r\n this.trackingDataId = trackingDataId;\r\n\r\n if (oldTrackingId === 'pending' && this.trackingDataId !== 'pending') {\r\n this.lastDwellTimeSent = 0;\r\n this.lastVideoTimeSent = 0;\r\n this.videoTrackingStopped = false;\r\n }\r\n\r\n if (this.startTime && oldTrackingId === 'pending') {\r\n this.sendDwellTime(false);\r\n }\r\n\r\n if (!this.intervalId && this.enabled && this.startTime) {\r\n this.intervalId = setInterval(() => {\r\n if (document.visibilityState === 'visible' && this.startTime) {\r\n this.sendDwellTime(false);\r\n }\r\n }, 30000);\r\n }\r\n }\r\n\r\n /**\r\n * Limpia todos los listeners y timers.\r\n */\r\n destroy(): void {\r\n this.stop();\r\n }\r\n\r\n // ====================================\r\n // PRIVATE\r\n // ====================================\r\n\r\n private checkLocalStorageForId(): void {\r\n if (typeof window === 'undefined') return;\r\n\r\n if (!this.trackingDataId || this.trackingDataId === 'pending') {\r\n const tid = localStorage.getItem('tracking_id') || localStorage.getItem('landing_tracking_id');\r\n if (tid) this.updateTrackingId(tid);\r\n }\r\n }\r\n\r\n private async sendDwellTime(isFinal: boolean = false): Promise<void> {\r\n if (!isTrackingAPIInitialized()) return;\r\n\r\n this.checkLocalStorageForId();\r\n\r\n if (!this.startTime || this.isSending) return;\r\n\r\n if (!this.trackingDataId || this.trackingDataId === 'pending') return;\r\n\r\n const trackingIdNum = typeof this.trackingDataId === 'string' ? parseInt(this.trackingDataId, 10) : this.trackingDataId;\r\n\r\n if (isNaN(trackingIdNum as number) || (trackingIdNum as number) <= 0) return;\r\n\r\n const elapsedTime = this.getElapsedTime();\r\n if (elapsedTime < 1 && !isFinal) return;\r\n\r\n this.isSending = true;\r\n const config = getAPIConfig();\r\n const token = config.getAuthToken?.() ?? null;\r\n\r\n try {\r\n const url = `${config.baseUrl}/tracking/${trackingIdNum}`;\r\n\r\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\r\n if (token) headers.Authorization = `Bearer ${token}`;\r\n\r\n const body: Record<string, unknown> = { dwellTime: elapsedTime };\r\n\r\n if (this.videoTimeWatched > 0 && !this.videoTrackingStopped) {\r\n body.videoTimeWatched = this.videoTimeWatched;\r\n body.videoCompleted = this.videoCompleted;\r\n }\r\n\r\n this.lastDwellTimeSent = elapsedTime;\r\n if (this.videoTimeWatched > 0 && !this.videoTrackingStopped) {\r\n this.lastVideoTimeSent = this.videoTimeWatched;\r\n }\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), 10000);\r\n\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers,\r\n body: JSON.stringify(body),\r\n keepalive: isFinal,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n throw new Error(`Error ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n this.onSuccess?.();\r\n this.clearPendingUpdate();\r\n } catch (error: unknown) {\r\n const err = error as { name?: string; message?: string };\r\n const isNetworkError =\r\n err.name === 'AbortError' || err.name === 'TimeoutError' || (err.name === 'TypeError' && err.message?.includes('Failed to fetch'));\r\n\r\n if (token) this.savePendingUpdate(elapsedTime);\r\n\r\n if (this.onError && !isNetworkError) {\r\n this.onError(error instanceof Error ? error : new Error('Error desconocido'));\r\n }\r\n } finally {\r\n this.isSending = false;\r\n }\r\n }\r\n\r\n private handleBeforeUnload(_event: BeforeUnloadEvent): void {\r\n this.sendDwellTimeWithBeacon();\r\n }\r\n\r\n private handleVisibilityChange(): void {\r\n if (document.visibilityState === 'hidden') {\r\n if (this.pauseStartTime === null && this.startTime) {\r\n this.pauseStartTime = Date.now();\r\n this.sendDwellTime(false);\r\n }\r\n } else if (document.visibilityState === 'visible') {\r\n if (this.pauseStartTime !== null) {\r\n this.pausedTime += Math.floor((Date.now() - this.pauseStartTime) / 1000);\r\n this.pauseStartTime = null;\r\n } else if (!this.startTime) {\r\n this.startTime = Date.now();\r\n this.pausedTime = 0;\r\n this.pauseStartTime = null;\r\n }\r\n }\r\n }\r\n\r\n private sendDwellTimeWithBeacon(): void {\r\n if (!isTrackingAPIInitialized()) return;\r\n\r\n this.checkLocalStorageForId();\r\n if (!this.startTime || !this.trackingDataId || this.trackingDataId === 'pending') return;\r\n\r\n const trackingIdNum = typeof this.trackingDataId === 'string' ? parseInt(this.trackingDataId, 10) : this.trackingDataId;\r\n\r\n if (isNaN(trackingIdNum as number) || (trackingIdNum as number) <= 0) return;\r\n\r\n const config = getAPIConfig();\r\n const elapsedTime = this.getElapsedTime();\r\n const token = config.getAuthToken?.() ?? null;\r\n\r\n const body: Record<string, unknown> = { dwellTime: elapsedTime };\r\n if (this.videoTimeWatched > 0 && !this.videoTrackingStopped) {\r\n body.videoTimeWatched = this.videoTimeWatched;\r\n body.videoCompleted = this.videoCompleted;\r\n }\r\n\r\n if (token) this.savePendingUpdate(elapsedTime);\r\n\r\n const url = `${config.baseUrl}/tracking/${trackingIdNum}`;\r\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\r\n if (token) headers.Authorization = `Bearer ${token}`;\r\n\r\n fetch(url, {\r\n method: 'PATCH',\r\n headers,\r\n body: JSON.stringify(body),\r\n keepalive: true,\r\n })\r\n .then((response) => {\r\n if (response.ok) this.clearPendingUpdate();\r\n })\r\n .catch(() => {});\r\n }\r\n\r\n private savePendingUpdate(time: number): void {\r\n if (typeof window === 'undefined' || !this.trackingDataId) return;\r\n try {\r\n sessionStorage.setItem('dwellTime_pending', JSON.stringify({ trackingDataId: this.trackingDataId, time, timestamp: Date.now() }));\r\n } catch {\r\n // sessionStorage may be unavailable\r\n }\r\n }\r\n\r\n private async retryPendingUpdates(): Promise<void> {\r\n if (typeof window === 'undefined' || !isTrackingAPIInitialized()) return;\r\n\r\n try {\r\n const pendingData = sessionStorage.getItem('dwellTime_pending');\r\n if (!pendingData) return;\r\n\r\n const { trackingDataId, time } = JSON.parse(pendingData);\r\n if (trackingDataId !== this.trackingDataId) {\r\n this.clearPendingUpdate();\r\n return;\r\n }\r\n\r\n const config = getAPIConfig();\r\n const token = config.getAuthToken?.() ?? null;\r\n if (!token) {\r\n this.clearPendingUpdate();\r\n return;\r\n }\r\n\r\n const url = `${config.baseUrl}/tracking/${trackingDataId}`;\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\r\n body: JSON.stringify({ dwellTime: time }),\r\n });\r\n\r\n if (response.ok) this.clearPendingUpdate();\r\n } catch {\r\n // Retry silently\r\n }\r\n }\r\n\r\n private clearPendingUpdate(): void {\r\n if (typeof window === 'undefined') return;\r\n try {\r\n sessionStorage.removeItem('dwellTime_pending');\r\n } catch {\r\n // sessionStorage may be unavailable\r\n }\r\n }\r\n\r\n private cleanupListeners(): void {\r\n if (typeof window === 'undefined') return;\r\n window.removeEventListener('beforeunload', this.boundBeforeUnload);\r\n document.removeEventListener('visibilitychange', this.boundVisibilityChange);\r\n }\r\n\r\n private cleanup(): void {\r\n if (typeof window === 'undefined') return;\r\n this.cleanupListeners();\r\n\r\n if (this.intervalId) {\r\n clearInterval(this.intervalId);\r\n this.intervalId = null;\r\n }\r\n }\r\n}\r\n\r\n// Singleton para uso global\r\nexport const dwellTimeTracker = new DwellTimeTracker();\r\n\r\n/**\r\n * Inicia el tracking del tiempo de permanencia.\r\n */\r\nexport const startDwellTimeTracking = (config: DwellTimeConfig): void => {\r\n dwellTimeTracker.start(config);\r\n};\r\n\r\n/**\r\n * Detiene el tracking y envía el tiempo acumulado.\r\n */\r\nexport const stopDwellTimeTracking = (): void => {\r\n dwellTimeTracker.stop();\r\n};\r\n","/**\r\n * Tracking Queries — Consultas GET al backend de tracking.\r\n * Migrado de TrackingService.ts y LeadTrackingService.ts.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { TrackingLead, LeadTrackingData } from '../core/types';\r\nimport { apiGet, apiPost } from './api-client';\r\n\r\n/**\r\n * Obtiene los datos de un tracking lead por su ID.\r\n *\r\n * @example\r\n * ```ts\r\n * const tracking = await getTrackingById(123);\r\n * console.log(tracking.videoTimeWatched, tracking.dwellTime);\r\n * ```\r\n */\r\nexport const getTrackingById = async (trackingId: number | string): Promise<TrackingLead> => {\r\n return apiGet<TrackingLead>(`/tracking/${trackingId}`);\r\n};\r\n\r\n/**\r\n * Obtiene un lead con sus datos de tracking asociados.\r\n * Procesa la respuesta para extraer videoVisto, tiempoReproducido, etc.\r\n *\r\n * @example\r\n * ```ts\r\n * const data = await getLeadWithTracking('456');\r\n * console.log(data.videoVisto, data.dwellTime);\r\n * ```\r\n */\r\nexport const getLeadWithTracking = async (leadId: string): Promise<LeadTrackingData> => {\r\n const defaultData: LeadTrackingData = {\r\n videoVisto: false,\r\n tiempoReproducido: '00:00',\r\n envioWhatsapp: false,\r\n videoTimeWatched: 0,\r\n dwellTime: 0,\r\n };\r\n\r\n try {\r\n const data = await apiGet<Record<string, unknown>>(`/leads/${leadId}/with-tracking`);\r\n\r\n // Extraer tracking info del array trackingData\r\n const trackingDataArray = data.trackingData as Array<Record<string, unknown>> | undefined;\r\n const trackingInfo = trackingDataArray && trackingDataArray.length > 0 ? trackingDataArray[0] : null;\r\n\r\n // Datos del nivel superior del lead\r\n const leadData = data as {\r\n accessUrl?: string;\r\n nameForm?: string;\r\n msgForm?: string;\r\n plataforma?: string;\r\n platform?: string;\r\n aliasName?: string;\r\n campaignName?: string;\r\n };\r\n\r\n if (!trackingInfo) {\r\n return {\r\n ...defaultData,\r\n accessUrl: leadData.accessUrl,\r\n nameForm: leadData.nameForm,\r\n msgForm: leadData.msgForm,\r\n platform: leadData.plataforma || leadData.platform,\r\n aliasName: leadData.aliasName || leadData.campaignName,\r\n };\r\n }\r\n\r\n const formatTime = (seconds: number): string => {\r\n const minutes = Math.floor(seconds / 60);\r\n const remainingSeconds = seconds % 60;\r\n return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\r\n };\r\n\r\n const videoTimeWatched = (trackingInfo.videoTimeWatched as number) || 0;\r\n const dwellTime = (trackingInfo.dwellTime as number) || (trackingInfo.dwell_time as number) || 0;\r\n\r\n return {\r\n videoVisto: (trackingInfo.videoCompleted as boolean) || false,\r\n tiempoReproducido: videoTimeWatched ? formatTime(videoTimeWatched) : '00:00',\r\n envioWhatsapp: (trackingInfo.whatsappSent as boolean) || false,\r\n accessUrl: (trackingInfo.accessUrl as string) || leadData.accessUrl,\r\n nameForm: (trackingInfo.nameForm as string) || leadData.nameForm,\r\n msgForm: (trackingInfo.msgForm as string) || leadData.msgForm,\r\n platform: leadData.plataforma || leadData.platform || (trackingInfo.platform as string),\r\n aliasName: leadData.aliasName || leadData.campaignName || (trackingInfo.aliasName as string),\r\n trackingId: (trackingInfo as { id?: number }).id,\r\n videoTimeWatched,\r\n dwellTime,\r\n };\r\n } catch {\r\n return defaultData;\r\n }\r\n};\r\n\r\n/**\r\n * Genera un link de tracking para un funnel.\r\n *\r\n * @example\r\n * ```ts\r\n * const { link } = await generateTrackingLink(1, 'mi-dominio.com');\r\n * ```\r\n */\r\nexport const generateTrackingLink = async (funnelId: number, customDomain: string): Promise<{ link: string }> => {\r\n return apiPost<{ link: string }>('/tracking/generate-link', {\r\n funnel_id: funnelId,\r\n custom_domain: customDomain,\r\n });\r\n};\r\n"]}