veo-sdk 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugins/plugin.ts","../src/plugins/guides/preview-mode.ts","../src/plugins/guides/guide-frequency-cache.ts","../src/plugins/guides/guide-resolver-client.ts","../src/plugins/guides/guide-tracker-client.ts","../src/plugins/guides/guide-tracker-queue.ts","../src/plugins/guides/walkthrough-state.ts","../src/plugins/guides/guides-controller.ts","../src/plugins/guides/index.ts"],"names":[],"mappings":"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","file":"chunk-R4E3LIDB.mjs","sourcesContent":["import type { VeoPlugin } from '../types';\n\n/**\n * Helper de identidad para definir un plugin con inferencia de tipos.\n * No transforma nada; mejora la ergonomía y deja un punto de extensión futuro.\n */\nexport function definePlugin(plugin: VeoPlugin): VeoPlugin {\n return plugin;\n}\n","/**\n * Modo PREVIEW POR LINK: la app del cliente se abre con\n * `?veoPreview=<token>` (link generado desde el dashboard) y el SDK canjea\n * el token contra `POST /v1/guides/preview-resolve` para renderizar ESA\n * guía como vista previa — aunque esté en draft — sobre la app real.\n *\n * A diferencia del modo builder no hay puente postMessage ni dashboard\n * abierto: es un link compartible para que el equipo pruebe la guía sin\n * publicarla. Reusa `previewGuide` (sin tracking/frecuencia/resolver) y\n * monta un chip flotante con \"volver a mostrar\" y \"cerrar\".\n *\n * Vive en el bundle de guías (`veo-guides.js`), NO en el `veo.js` core —\n * el core solo detecta el query param y dispara la carga del bundle.\n */\nimport { hasDocument } from '../../utils/safe-env';\nimport { previewGuide } from './guide-preview';\nimport type { ResolvedGuide } from './types';\n\nexport interface PreviewModeOptions {\n apiKey: string;\n apiUrl: string;\n /** Token firmado del link (`?veoPreview=<token>`). */\n token: string;\n debug?: boolean;\n}\n\nexport interface PreviewModeHandle {\n /** Cierra la preview y quita el chip. Idempotente. */\n teardown(): void;\n}\n\nlet active: PreviewModeHandle | null = null;\n\n/**\n * Canjea el token y renderiza la guía como vista previa + chip de control.\n * Si el token es inválido/expirado, el chip lo informa (solo quien tiene el\n * link lo ve). Solo una sesión de preview activa a la vez.\n */\nexport async function runPreviewMode(opts: PreviewModeOptions): Promise<PreviewModeHandle | null> {\n if (!hasDocument()) return null;\n active?.teardown();\n\n let guide: ResolvedGuide | null = null;\n try {\n const res = await fetch(`${opts.apiUrl}/v1/guides/preview-resolve`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': opts.apiKey },\n body: JSON.stringify({ token: opts.token }),\n });\n if (res.ok) {\n const data = (await res.json()) as { guide?: ResolvedGuide };\n guide = data.guide ?? null;\n } else if (opts.debug) {\n console.warn('[veo] preview-resolve respondió', res.status);\n }\n } catch (err) {\n if (opts.debug) console.warn('[veo] preview-resolve falló:', err);\n }\n\n /**\n * En el link de preview el envío de forms es REAL: corre sobre la app del\n * cliente con el SDK inicializado, así que la respuesta se guarda en el\n * usuario que está probando (su propia identidad) — permite verificar el\n * flujo completo props→segmentos sin tocar a nadie más.\n */\n const submitToBackend = async (answers: Record<string, unknown>): Promise<boolean> => {\n if (!guide) return false;\n const veo = (\n window as unknown as {\n veo?: { getEndUserId?: () => string | null; getAnonymousId?: () => string };\n }\n ).veo;\n const endUserId = veo?.getEndUserId?.() ?? veo?.getAnonymousId?.() ?? null;\n if (!endUserId) return false;\n try {\n const res = await fetch(`${opts.apiUrl}/v1/guides/${guide.guideId}/form-response`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': opts.apiKey },\n body: JSON.stringify({ endUserId, answers }),\n });\n return res.ok;\n } catch {\n return false;\n }\n };\n\n let preview: { close(): void } | null = null;\n const show = (): void => {\n if (!guide) return;\n preview?.close();\n preview = previewGuide({\n guideType: guide.guideType,\n guideSteps: guide.guideSteps,\n activationRules: guide.activationRules,\n guideName: guide.guideName,\n formSubmit: submitToBackend,\n formSubmitNote: 'Vista previa: guardado en TU usuario para probar el flujo.',\n });\n };\n\n const chip = mountChip({\n label: guide ? `Vista previa: ${guide.guideName}` : 'Link de preview inválido o vencido',\n error: !guide,\n onReshow: guide ? show : null,\n onClose: () => handle.teardown(),\n });\n\n const handle: PreviewModeHandle = {\n teardown() {\n preview?.close();\n preview = null;\n chip.remove();\n if (active === handle) active = null;\n },\n };\n active = handle;\n show();\n return handle;\n}\n\ninterface ChipOptions {\n label: string;\n error: boolean;\n onReshow: (() => void) | null;\n onClose: () => void;\n}\n\n/** Chip flotante (Shadow DOM, abajo-derecha) con re-mostrar y cerrar. */\nfunction mountChip(opts: ChipOptions): { remove(): void } {\n const host = document.createElement('div');\n host.setAttribute('data-veo-preview-chip', '');\n const root = host.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = `\n .chip { position: fixed; bottom: 16px; right: 16px; z-index: 2147483647;\n display: flex; align-items: center; gap: 8px; padding: 8px 12px;\n background: #111827; color: #f9fafb; border-radius: 9999px;\n font: 500 12px/1.2 system-ui, sans-serif; box-shadow: 0 4px 12px rgba(0,0,0,.25); }\n .chip.error { background: #7f1d1d; }\n .label { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n button { all: unset; cursor: pointer; padding: 2px 6px; border-radius: 9999px;\n font-size: 12px; line-height: 1; }\n button:hover { background: rgba(255,255,255,.15); }\n `;\n root.appendChild(style);\n\n const chip = document.createElement('div');\n chip.className = opts.error ? 'chip error' : 'chip';\n\n const label = document.createElement('span');\n label.className = 'label';\n label.textContent = opts.label;\n chip.appendChild(label);\n\n if (opts.onReshow) {\n const reshow = document.createElement('button');\n reshow.textContent = '↻';\n reshow.title = 'Volver a mostrar la guía';\n reshow.addEventListener('click', opts.onReshow);\n chip.appendChild(reshow);\n }\n\n const close = document.createElement('button');\n close.textContent = '✕';\n close.title = 'Salir de la vista previa';\n close.addEventListener('click', opts.onClose);\n chip.appendChild(close);\n\n root.appendChild(chip);\n document.body.appendChild(host);\n return { remove: () => host.remove() };\n}\n","import {\n FREQUENCY_CACHE_KEY_PREFIX,\n FREQUENCY_CACHE_MAX_ENTRIES,\n FREQUENCY_CACHE_TTL_MS,\n} from './constants';\nimport type { DisplayFrequency, FrequencyCacheEntry, FrequencyStatus } from './types';\n\n/** Prioridad de status para no degradar shown→dismissed→… */\nconst STATUS_PRIORITY: Record<FrequencyStatus, number> = {\n shown: 1,\n dismissed: 2,\n completed: 2,\n};\n\n/**\n * Namespace short y estable derivado del apiKey. NO es cripto: solo evita\n * que dos apps que comparten el navegador pisen sus caches. El apiKey\n * público (`pk_*`) ya es workspace-único, así que usar sus últimos 16\n * caracteres alcanza para diferenciar.\n */\nexport function namespaceFromApiKey(apiKey: string): string {\n return apiKey.slice(-16) || 'default';\n}\n\n/**\n * Cache persistente de \"qué guías ya vio/cerró este usuario\". Vive en\n * `localStorage` con key namespaceada para evitar colisión entre\n * workspaces que corren en el mismo navegador.\n *\n * No es source of truth — el backend siempre manda. Esta cache solo\n * evita el flash visual de re-pintar una guía que el usuario ya cerró\n * antes de que el roundtrip al backend termine.\n */\nexport class GuideFrequencyCache {\n private readonly storageKey: string;\n private cache: Map<string, FrequencyCacheEntry>;\n\n constructor(namespace: string) {\n this.storageKey = `${FREQUENCY_CACHE_KEY_PREFIX}${namespace}`;\n this.cache = this.load();\n this.prune();\n }\n\n /**\n * Decide si una guía debe filtrarse localmente antes de pintarla.\n *\n * - `every_visit` / `always` → nunca filtra (siempre re-pinta).\n * - `once` → cualquier entry registrada filtra (verla ya cuenta).\n * - `until_dismissed` → si fue descartada O COMPLETADA (responder un\n * form / terminar un walkthrough es más fuerte que descartar — sin\n * esto, una encuesta seguiría preguntando después de respondida).\n */\n shouldFilter(guideId: string, displayFrequency: DisplayFrequency): boolean {\n if (displayFrequency === 'every_visit' || displayFrequency === 'always') return false;\n\n const entry = this.cache.get(guideId);\n if (!entry) return false;\n\n if (displayFrequency === 'once') return true;\n if (displayFrequency === 'until_dismissed') {\n return entry.status === 'dismissed' || entry.status === 'completed';\n }\n // `until_answered` (forms): solo COMPLETAR filtra localmente. El descarte\n // no la silencia — y si las props ya tienen valor por otro medio, es el\n // BACKEND quien la excluye del resolve (acá no conocemos los traits).\n if (displayFrequency === 'until_answered') return entry.status === 'completed';\n return false;\n }\n\n /**\n * Registra/actualiza la entry de una guía. Nunca degrada un estado más\n * fuerte (no convierte `dismissed` en `shown` por un re-render). Persiste\n * cada llamada — escribir a localStorage es lo bastante barato.\n */\n record(guideId: string, status: FrequencyStatus): void {\n const existing = this.cache.get(guideId);\n if (existing && STATUS_PRIORITY[status] < STATUS_PRIORITY[existing.status]) {\n return;\n }\n this.cache.set(guideId, {\n guideId,\n status,\n lastInteractionAt: Date.now(),\n });\n this.persist();\n }\n\n /** Limpia el cache (botón \"reset\" del demo, tests). */\n clear(): void {\n this.cache.clear();\n this.persist();\n }\n\n /** Útil para debugging — devuelve un snapshot. */\n snapshot(): FrequencyCacheEntry[] {\n return Array.from(this.cache.values());\n }\n\n /**\n * Limpia entries expiradas por TTL y, si aún excede el límite, descarta\n * las más viejas hasta caber. Se ejecuta una vez en el constructor; no\n * vale la pena correrlo a cada lectura.\n */\n private prune(): void {\n const now = Date.now();\n let mutated = false;\n\n for (const [id, entry] of this.cache) {\n if (now - entry.lastInteractionAt > FREQUENCY_CACHE_TTL_MS) {\n this.cache.delete(id);\n mutated = true;\n }\n }\n\n if (this.cache.size > FREQUENCY_CACHE_MAX_ENTRIES) {\n const sorted = Array.from(this.cache.entries()).sort(\n (a, b) => a[1].lastInteractionAt - b[1].lastInteractionAt,\n );\n const excess = this.cache.size - FREQUENCY_CACHE_MAX_ENTRIES;\n for (let i = 0; i < excess; i++) {\n const tuple = sorted[i];\n if (tuple) this.cache.delete(tuple[0]);\n }\n mutated = true;\n }\n\n if (mutated) this.persist();\n }\n\n private load(): Map<string, FrequencyCacheEntry> {\n if (typeof localStorage === 'undefined') return new Map();\n try {\n const raw = localStorage.getItem(this.storageKey);\n if (!raw) return new Map();\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed)) return new Map();\n const entries: Array<[string, FrequencyCacheEntry]> = [];\n for (const item of parsed) {\n if (\n item &&\n typeof item === 'object' &&\n typeof (item as FrequencyCacheEntry).guideId === 'string' &&\n typeof (item as FrequencyCacheEntry).lastInteractionAt === 'number' &&\n ['shown', 'dismissed', 'completed'].includes((item as FrequencyCacheEntry).status)\n ) {\n const e = item as FrequencyCacheEntry;\n entries.push([e.guideId, e]);\n }\n }\n return new Map(entries);\n } catch {\n return new Map();\n }\n }\n\n private persist(): void {\n if (typeof localStorage === 'undefined') return;\n try {\n const serialized = JSON.stringify(Array.from(this.cache.values()));\n localStorage.setItem(this.storageKey, serialized);\n } catch {\n // QuotaExceeded o similar — el cache es opcional, no rompemos la app.\n }\n }\n}\n","import type { ResolvedGuide, ResolveGuidesResponse } from './types';\n\n/**\n * Wrapper sobre `GET /v1/guides/resolve`. Nunca lanza: cualquier error de\n * red o de parsing devuelve un array vacío, para que el plugin no rompa\n * la app del cliente.\n *\n * Importante: el endpoint usa `?pageUrl=...` (no `?url=...`) — el backend\n * valida con class-validator `IsUrl({ require_protocol: true })`.\n */\nexport class GuideResolverClient {\n constructor(\n private readonly apiUrl: string,\n private readonly apiKey: string,\n private readonly debug = false,\n ) {}\n\n async resolve(endUserId: string, pageUrl: string): Promise<ResolvedGuide[]> {\n const params = new URLSearchParams({ endUserId, pageUrl });\n let response: Response;\n try {\n response = await fetch(`${this.apiUrl}/v1/guides/resolve?${params.toString()}`, {\n method: 'GET',\n headers: { 'X-Api-Key': this.apiKey },\n credentials: 'omit',\n });\n } catch (err) {\n if (this.debug) console.error('[veo] guides resolve fetch failed:', err);\n return [];\n }\n\n if (!response.ok) {\n if (this.debug) console.warn('[veo] guides resolve HTTP', response.status);\n return [];\n }\n\n try {\n const data = (await response.json()) as ResolveGuidesResponse;\n return Array.isArray(data.guides) ? data.guides : [];\n } catch (err) {\n if (this.debug) console.error('[veo] guides resolve parse failed:', err);\n return [];\n }\n }\n\n /**\n * Trae una guía específica por ID, sin pasar por la lógica de\n * activación. La usa el controller para resumir un walkthrough entre\n * páginas: el `resolve` no devuelve la guía si la URL actual no\n * matchea, pero el walkthrough activo debe poder consultarla igual.\n *\n * El endpoint backend (`GET /v1/guides/:guideId`) devuelve `GuideResponse`,\n * un superset de `ResolvedGuide` con campos de audit. Acá descartamos los\n * extra y nos quedamos con el shape que el resto del SDK ya consume.\n *\n * Devuelve `null` en cualquier error (404, red, parse) — el caller debe\n * tratarlo como \"guía ya no existe\" y cancelar el walkthrough limpiamente.\n */\n async fetchById(guideId: string): Promise<ResolvedGuide | null> {\n let response: Response;\n try {\n response = await fetch(`${this.apiUrl}/v1/guides/${encodeURIComponent(guideId)}`, {\n method: 'GET',\n headers: { 'X-Api-Key': this.apiKey },\n credentials: 'omit',\n });\n } catch (err) {\n if (this.debug) console.error('[veo] guides fetchById network failed:', err);\n return null;\n }\n\n if (!response.ok) {\n if (this.debug) console.warn('[veo] guides fetchById HTTP', response.status);\n return null;\n }\n\n try {\n const data = (await response.json()) as Partial<ResolvedGuide>;\n if (\n typeof data.guideId !== 'string' ||\n typeof data.guideName !== 'string' ||\n typeof data.guideType !== 'string' ||\n !Array.isArray(data.guideSteps) ||\n !data.activationRules ||\n typeof data.displayFrequency !== 'string' ||\n typeof data.displayPriority !== 'number'\n ) {\n if (this.debug) console.warn('[veo] guides fetchById: unexpected shape');\n return null;\n }\n return {\n guideId: data.guideId,\n guideName: data.guideName,\n guideType: data.guideType,\n guideSteps: data.guideSteps,\n activationRules: data.activationRules,\n displayFrequency: data.displayFrequency,\n displayPriority: data.displayPriority,\n };\n } catch (err) {\n if (this.debug) console.error('[veo] guides fetchById parse failed:', err);\n return null;\n }\n }\n}\n","import type { GuideInteractionPayload } from './types';\n\nexport interface InteractionRequest {\n guideId: string;\n payload: GuideInteractionPayload;\n}\n\n/**\n * Wire shape esperada por `POST /v1/guides/:id/interactions` en el backend.\n * Nuestro tipo interno (`GuideInteractionPayload`) usa `action`/`stepIndex`;\n * el backend exige `interactionType`/`stepPosition`. Esta función centraliza\n * la traducción.\n */\ninterface WireInteraction {\n endUserId: string;\n sessionId?: string;\n interactionType: GuideInteractionPayload['action'];\n stepPosition?: number;\n pageUrl?: string;\n pagePath?: string;\n}\n\nfunction toWire(payload: GuideInteractionPayload): WireInteraction {\n const wire: WireInteraction = {\n endUserId: payload.endUserId,\n interactionType: payload.action,\n };\n if (payload.sessionId) wire.sessionId = payload.sessionId;\n if (typeof payload.stepIndex === 'number') wire.stepPosition = payload.stepIndex;\n if (payload.pageUrl) wire.pageUrl = payload.pageUrl;\n if (payload.pagePath) wire.pagePath = payload.pagePath;\n return wire;\n}\n\n/**\n * Cliente HTTP puro para registrar interacciones de guías. No hace retry\n * ni queue — esa responsabilidad vive en `GuideTrackerQueue`.\n *\n * `send` lanza en error (queue puede reintentar). `sendBeacon` es síncrono,\n * \"best effort\", para el cierre de página: usa `navigator.sendBeacon` con\n * el apiKey como query param `?key=` (la única forma de autenticar con\n * sendBeacon, ya que no permite headers custom — el backend lo soporta\n * desde el ApiKeyGuard).\n */\nexport class GuideTrackerClient {\n constructor(\n private readonly apiUrl: string,\n private readonly apiKey: string,\n ) {}\n\n async send(request: InteractionRequest): Promise<void> {\n const url = this.buildUrl(request.guideId);\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'X-Api-Key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(toWire(request.payload)),\n credentials: 'omit',\n });\n\n if (!response.ok) {\n throw new Error(`guide interaction send failed: HTTP ${response.status}`);\n }\n }\n\n /**\n * Envío \"fire-and-forget\" en pagehide. Devuelve `false` si el navegador\n * no acepta el beacon (cola llena, no soportado) — en ese caso la queue\n * sabrá que perdió el envío.\n */\n sendBeacon(request: InteractionRequest): boolean {\n if (typeof navigator === 'undefined' || typeof navigator.sendBeacon !== 'function') {\n return false;\n }\n const url = `${this.buildUrl(request.guideId)}?key=${encodeURIComponent(this.apiKey)}`;\n const blob = new Blob([JSON.stringify(toWire(request.payload))], {\n type: 'application/json',\n });\n try {\n return navigator.sendBeacon(url, blob);\n } catch {\n return false;\n }\n }\n\n private buildUrl(guideId: string): string {\n return `${this.apiUrl}/v1/guides/${encodeURIComponent(guideId)}/interactions`;\n }\n}\n","import type { GuideTrackerClient, InteractionRequest } from './guide-tracker-client';\nimport type { QueuedInteraction } from './types';\n\nexport interface GuideTrackerQueueConfig {\n client: GuideTrackerClient;\n flushIntervalMs: number;\n batchSize: number;\n maxRetries: number;\n /**\n * Llamado cuando un item se descarta tras agotar `maxRetries`. El\n * plugin puede usarlo para `console.warn` en debug mode. Nunca debe\n * lanzar — si lo hace, se ignora silenciosamente.\n */\n onError?: (error: Error, item: QueuedInteraction) => void;\n}\n\n/**\n * Queue dedicada para `POST /v1/guides/:id/interactions`.\n *\n * Cada item es independiente (URL distinto por `guideId`), así que el\n * \"batch\" en realidad dispara N requests en paralelo. El `batchSize` es\n * el umbral para forzar un flush — no agrupa requests en uno solo.\n *\n * Retry:\n * - Si `send()` lanza, el item se devuelve al buffer con `attempts++`.\n * - El timer regular vuelve a intentar en el próximo tick.\n * - Al alcanzar `maxRetries`, se descarta llamando `onError`.\n *\n * En `pagehide`/`visibilitychange` (hidden) drena el buffer vía\n * `navigator.sendBeacon`. Best effort — no re-encola lo que el beacon\n * rechace porque la página ya se va.\n */\nexport class GuideTrackerQueue {\n private buffer: QueuedInteraction[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n private unloadCleanup: (() => void) | null = null;\n\n constructor(private readonly config: GuideTrackerQueueConfig) {\n this.startTimer();\n this.installUnloadHandler();\n }\n\n /** Tamaño actual del buffer (útil para debug/stats en el demo). */\n get size(): number {\n return this.buffer.length;\n }\n\n /**\n * Encola una interaction. Si el buffer alcanza `batchSize`, dispara\n * `flush()` inmediato.\n */\n enqueue(request: InteractionRequest): void {\n this.buffer.push({\n guideId: request.guideId,\n payload: request.payload,\n attempts: 0,\n enqueuedAt: Date.now(),\n });\n if (this.buffer.length >= this.config.batchSize) {\n void this.flush();\n }\n }\n\n /**\n * Envía todo el buffer en paralelo. Items que fallan vuelven al buffer\n * si todavía tienen reintentos disponibles. Idempotente con respecto a\n * flushes concurrentes (el segundo es un no-op).\n */\n async flush(): Promise<void> {\n if (this.flushing || this.buffer.length === 0) return;\n this.flushing = true;\n\n const batch = this.buffer.splice(0, this.buffer.length);\n const results = await Promise.allSettled(\n batch.map((item) =>\n this.config.client.send({ guideId: item.guideId, payload: item.payload }),\n ),\n );\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n const item = batch[i];\n if (!result || !item) continue;\n if (result.status === 'fulfilled') continue;\n\n item.attempts += 1;\n if (item.attempts < this.config.maxRetries) {\n this.buffer.push(item);\n } else {\n this.safeOnError(result.reason, item);\n }\n }\n\n this.flushing = false;\n }\n\n /**\n * Drena el buffer vía `sendBeacon`. Síncrono, sin retry. Para pagehide.\n */\n flushBeacon(): void {\n if (this.buffer.length === 0) return;\n const batch = this.buffer.splice(0, this.buffer.length);\n for (const item of batch) {\n this.config.client.sendBeacon({ guideId: item.guideId, payload: item.payload });\n }\n }\n\n destroy(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n this.unloadCleanup?.();\n this.unloadCleanup = null;\n }\n\n private startTimer(): void {\n if (typeof window === 'undefined') return;\n this.timer = setInterval(() => {\n void this.flush();\n }, this.config.flushIntervalMs);\n }\n\n private installUnloadHandler(): void {\n if (typeof window === 'undefined') return;\n const onPagehide = (): void => this.flushBeacon();\n const onVisibility = (): void => {\n if (document.visibilityState === 'hidden') this.flushBeacon();\n };\n window.addEventListener('pagehide', onPagehide);\n window.addEventListener('visibilitychange', onVisibility);\n this.unloadCleanup = () => {\n window.removeEventListener('pagehide', onPagehide);\n window.removeEventListener('visibilitychange', onVisibility);\n };\n }\n\n private safeOnError(reason: unknown, item: QueuedInteraction): void {\n if (!this.config.onError) return;\n const error = reason instanceof Error ? reason : new Error(String(reason));\n try {\n this.config.onError(error, item);\n } catch {\n // Un onError roto no debe afectar al resto del flush.\n }\n }\n}\n","import { WALKTHROUGH_ABANDONMENT_TIMEOUT_MS, WALKTHROUGH_STATE_KEY_PREFIX } from './constants';\nimport type { WalkthroughState } from './types';\n\n/**\n * Estado persistente del walkthrough activo. Solo permite UNO por\n * workspace (namespace de apiKey). Vive en `localStorage` para sobrevivir\n * recargas de página: el step actual + el guideId alcanzan para resumir\n * desde donde quedó el usuario.\n *\n * Si pasan más de `WALKTHROUGH_ABANDONMENT_TIMEOUT_MS` sin progreso, se\n * considera abandonado: la próxima llamada a `current()` lo limpia\n * silenciosamente. NO se reporta `dismissed` al backend en ese caso —\n * abandonarse no es un acto del usuario.\n */\nexport class WalkthroughStateManager {\n private readonly storageKey: string;\n private state: WalkthroughState | null = null;\n\n constructor(namespace: string) {\n this.storageKey = `${WALKTHROUGH_STATE_KEY_PREFIX}${namespace}`;\n this.state = this.load();\n if (this.state && this.isAbandoned(this.state)) {\n this.clear();\n }\n }\n\n /**\n * Estado del walkthrough activo. Devuelve `null` si no hay ninguno o si\n * el último progreso fue hace más del timeout (en ese caso también\n * limpia el storage como side-effect).\n */\n current(): WalkthroughState | null {\n if (!this.state) return null;\n if (this.isAbandoned(this.state)) {\n this.clear();\n return null;\n }\n return this.state;\n }\n\n /** Atajo legible para el controller. */\n hasActive(): boolean {\n return this.current() !== null;\n }\n\n /**\n * Inicia un nuevo walkthrough en step 0. Sobreescribe cualquier estado\n * previo — los callers (controller) son responsables de verificar\n * `hasActive()` antes si necesitan exclusividad.\n */\n start(guideId: string, totalSteps: number): WalkthroughState {\n const now = Date.now();\n this.state = {\n guideId,\n totalSteps,\n currentStepIndex: 0,\n startedAt: now,\n lastProgressAt: now,\n };\n this.persist();\n return this.state;\n }\n\n /**\n * Avanza al siguiente step. Si el step resultante excede `totalSteps`,\n * devuelve `null` y NO toca el estado — el controller debe interpretar\n * eso como \"ya estamos en el último, no hay próximo\" y disparar\n * `complete` vía el handler del botón \"Finalizar\".\n */\n advance(): WalkthroughState | null {\n if (!this.state) return null;\n\n const next = this.state.currentStepIndex + 1;\n if (next >= this.state.totalSteps) return null;\n\n this.state = {\n ...this.state,\n currentStepIndex: next,\n lastProgressAt: Date.now(),\n };\n this.persist();\n return this.state;\n }\n\n /**\n * Retrocede al step anterior. En step 0 no hace nada y devuelve el\n * estado tal cual (el botón \"Atrás\" no debería estar visible en el\n * primer step, pero por defensa el manager también lo guard-ea).\n */\n back(): WalkthroughState | null {\n if (!this.state) return null;\n if (this.state.currentStepIndex === 0) return this.state;\n\n this.state = {\n ...this.state,\n currentStepIndex: this.state.currentStepIndex - 1,\n lastProgressAt: Date.now(),\n };\n this.persist();\n return this.state;\n }\n\n /** Limpia el estado activo (skip, complete, abandono, guía borrada). */\n clear(): void {\n this.state = null;\n if (typeof localStorage === 'undefined') return;\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // Storage bloqueado — no rompemos la app.\n }\n }\n\n private isAbandoned(state: WalkthroughState): boolean {\n return Date.now() - state.lastProgressAt > WALKTHROUGH_ABANDONMENT_TIMEOUT_MS;\n }\n\n private load(): WalkthroughState | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(this.storageKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== 'object') return null;\n const candidate = parsed as Partial<WalkthroughState>;\n if (\n typeof candidate.guideId !== 'string' ||\n typeof candidate.totalSteps !== 'number' ||\n typeof candidate.currentStepIndex !== 'number' ||\n typeof candidate.startedAt !== 'number' ||\n typeof candidate.lastProgressAt !== 'number'\n ) {\n return null;\n }\n return candidate as WalkthroughState;\n } catch {\n return null;\n }\n }\n\n private persist(): void {\n if (typeof localStorage === 'undefined' || !this.state) return;\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(this.state));\n } catch {\n // Quota exceeded — silently fail. El walkthrough en memoria sigue.\n }\n }\n}\n","import type { VeoClient } from '../../types';\nimport {\n DEFAULT_TRACKER_BATCH_SIZE,\n DEFAULT_TRACKER_FLUSH_INTERVAL_MS,\n DEFAULT_TRACKER_MAX_RETRIES,\n} from './constants';\nimport { GuideFrequencyCache, namespaceFromApiKey } from './guide-frequency-cache';\nimport { GuideResolverClient } from './guide-resolver-client';\nimport { GuideTrackerClient } from './guide-tracker-client';\nimport { GuideTrackerQueue } from './guide-tracker-queue';\nimport { BannerRenderer } from './renderers/banner-renderer';\nimport type { BaseRenderer } from './renderers/base-renderer';\nimport { CustomRenderer } from './renderers/custom-renderer';\nimport { FormRenderer } from './renderers/form-renderer';\nimport { InlineCustomRenderer } from './renderers/inline-custom-renderer';\nimport { InlineFormRenderer } from './renderers/inline-form-renderer';\nimport { InlineRenderer } from './renderers/inline-renderer';\nimport { ModalRenderer } from './renderers/modal-renderer';\nimport { TooltipRenderer } from './renderers/tooltip-renderer';\nimport { WalkthroughRenderer } from './renderers/walkthrough-renderer';\nimport type {\n FrequencyStatus,\n GuideInteractionAction,\n GuideInteractionEvent,\n GuideType,\n ResolvedGuide,\n WalkthroughCallbacks,\n} from './types';\nimport { WalkthroughStateManager } from './walkthrough-state';\n\nexport interface GuidesControllerConfig {\n apiUrl: string;\n apiKey: string;\n debug?: boolean;\n /** Override del resolver (tests). */\n resolver?: GuideResolverClient;\n /** Override del tracker queue (tests). */\n trackerQueue?: GuideTrackerQueue;\n /** Override del cache (tests). */\n frequencyCache?: GuideFrequencyCache;\n /** Override del walkthrough state manager (tests). */\n walkthroughState?: WalkthroughStateManager;\n}\n\n/** Mapeo `action → cache status`. Solo acciones terminales mutan el cache. */\nconst STATUS_BY_ACTION: Record<GuideInteractionAction, FrequencyStatus | null> = {\n shown: 'shown',\n dismissed: 'dismissed',\n cta_clicked: null,\n step_advanced: null,\n step_back: null,\n completed: 'completed',\n};\n\n/**\n * Orquesta el ciclo de vida de las guías:\n *\n * 1. `pageview`/`identify` → `checkGuides(url, sessionId)`.\n * 2. Si hay un walkthrough activo (estado persistido en localStorage),\n * tiene prioridad: se intenta resumir en la página actual antes de\n * consultar nuevas guías. Si el selector del step actual aparece,\n * se pinta; si no, se cancela el walkthrough limpiamente.\n * 3. Si no hay walkthrough activo, se consulta `/v1/guides/resolve` y\n * se procesa cada guía:\n * - `walkthrough` con varios steps → arranca un walkthrough\n * (uno a la vez; el resto se ignora si ya hay uno).\n * - single-step → modal/banner/tooltip como antes.\n * 4. Cada interaction actualiza el cache local Y se encola para\n * `POST /v1/guides/:id/interactions`.\n *\n * Dedupe: `dispatched` guarda `${guideId}:${action}` ya encolados en la\n * sesión actual del SDK. Las acciones por-step de walkthroughs no\n * usan dedupe — cada `step_advanced` puede repetirse y representa una\n * navegación distinta.\n */\nexport class GuidesController {\n private readonly resolver: GuideResolverClient;\n private readonly trackerQueue: GuideTrackerQueue;\n private readonly frequencyCache: GuideFrequencyCache;\n private readonly walkthroughState: WalkthroughStateManager;\n private readonly debug: boolean;\n /** Para `POST /v1/guides/:id/form-response` (respuestas de guías form). */\n private readonly apiUrl: string;\n private readonly apiKey: string;\n private readonly activeRenderers = new Set<BaseRenderer>();\n /**\n * Guías single-step actualmente en pantalla, por `guideId`. Evita repintar/\n * duplicar la misma guía en cada pageview de una SPA (p.ej. una guía inline\n * anclada a un elemento persistente). Se libera al cerrarse la guía.\n */\n private readonly activeByGuideId = new Map<string, BaseRenderer>();\n private readonly dispatched = new Set<string>();\n private activeWalkthroughRenderer: WalkthroughRenderer | null = null;\n private activeWalkthroughGuide: ResolvedGuide | null = null;\n\n constructor(\n private readonly client: VeoClient,\n config: GuidesControllerConfig,\n ) {\n this.debug = config.debug === true;\n this.apiUrl = config.apiUrl;\n this.apiKey = config.apiKey;\n this.resolver =\n config.resolver ?? new GuideResolverClient(config.apiUrl, config.apiKey, this.debug);\n\n if (config.trackerQueue) {\n this.trackerQueue = config.trackerQueue;\n } else {\n const httpClient = new GuideTrackerClient(config.apiUrl, config.apiKey);\n this.trackerQueue = new GuideTrackerQueue({\n client: httpClient,\n flushIntervalMs: DEFAULT_TRACKER_FLUSH_INTERVAL_MS,\n batchSize: DEFAULT_TRACKER_BATCH_SIZE,\n maxRetries: DEFAULT_TRACKER_MAX_RETRIES,\n onError: (err, item) => {\n if (this.debug) {\n console.warn(\n `[veo] dropped guide interaction after retries: guideId=${item.guideId} action=${item.payload.action}`,\n err,\n );\n }\n },\n });\n }\n\n const namespace = namespaceFromApiKey(config.apiKey);\n this.frequencyCache = config.frequencyCache ?? new GuideFrequencyCache(namespace);\n this.walkthroughState = config.walkthroughState ?? new WalkthroughStateManager(namespace);\n }\n\n /** Cuántas interactions hay pendientes de envío. Útil para debug en demo. */\n get pendingInteractions(): number {\n return this.trackerQueue.size;\n }\n\n /** Limpia el cache local (botón \"reset\" del demo, tests). */\n clearFrequencyCache(): void {\n this.frequencyCache.clear();\n }\n\n /** Limpia el walkthrough activo (debug del demo). */\n clearWalkthroughState(): void {\n this.tearDownWalkthrough();\n }\n\n /** Punto de entrada principal. Llamado en cada pageview/identify. */\n async checkGuides(pageUrl: string, sessionId: string): Promise<void> {\n const endUserId = this.client.getEndUserId();\n if (!endUserId) {\n if (this.debug) console.log('[veo] guides: skipped, no endUserId yet');\n return;\n }\n\n if (await this.tryResumeWalkthrough(endUserId, sessionId, pageUrl)) {\n return;\n }\n\n let guides: ResolvedGuide[];\n try {\n guides = await this.resolver.resolve(endUserId, pageUrl);\n } catch (err) {\n if (this.debug) console.error('[veo] guides resolver threw:', err);\n return;\n }\n if (this.debug) console.log(`[veo] guides: ${guides.length} eligible at ${pageUrl}`);\n\n for (const guide of guides) {\n if (this.frequencyCache.shouldFilter(guide.guideId, guide.displayFrequency)) {\n if (this.debug) console.log(`[veo] guides: filtered locally guideId=${guide.guideId}`);\n continue;\n }\n\n // Ya está en pantalla → no repintar/duplicar (clave en SPAs: cada\n // navegación dispara un pageview, pero la guía sigue montada).\n if (this.activeByGuideId.has(guide.guideId)) {\n if (this.debug) console.log(`[veo] guides: already shown guideId=${guide.guideId}`);\n continue;\n }\n\n if (guide.guideType === 'walkthrough' && guide.guideSteps.length > 1) {\n if (this.walkthroughState.hasActive()) {\n if (this.debug)\n console.log(`[veo] guides: walkthrough ${guide.guideId} skipped (another active)`);\n continue;\n }\n await this.startWalkthrough(guide, endUserId, sessionId, pageUrl);\n // No retornamos: las guías single-step pueden seguir mostrándose\n // en paralelo. Solo bloqueamos OTROS walkthroughs vía hasActive().\n continue;\n }\n\n this.runSingleStepRender(guide, sessionId, pageUrl);\n }\n }\n\n /** Cierra todas las guías activas, limpia cache de dispatch y para timers. */\n destroy(): void {\n for (const renderer of this.activeRenderers) {\n try {\n renderer.destroy();\n } catch (err) {\n if (this.debug) console.error('[veo] renderer destroy failed:', err);\n }\n }\n this.activeRenderers.clear();\n this.activeByGuideId.clear();\n if (this.activeWalkthroughRenderer) {\n try {\n this.activeWalkthroughRenderer.destroy();\n } catch {\n // swallow — el cleanup no debe propagar\n }\n this.activeWalkthroughRenderer = null;\n this.activeWalkthroughGuide = null;\n }\n this.dispatched.clear();\n this.trackerQueue.destroy();\n }\n\n private runSingleStepRender(guide: ResolvedGuide, sessionId: string, pageUrl: string): void {\n const renderer = this.createSingleStepRenderer(guide.guideType);\n if (!renderer) return;\n\n // Reservar el slot YA (antes del delay) para que pageviews rápidos no\n // disparen dos renders de la misma guía.\n this.activeByGuideId.set(guide.guideId, renderer);\n\n const delayMs = guide.activationRules.delayMs ?? 0;\n window.setTimeout(\n () => this.mountSingleStepRenderer(guide, renderer, sessionId, pageUrl),\n delayMs,\n );\n }\n\n private mountSingleStepRenderer(\n guide: ResolvedGuide,\n renderer: BaseRenderer,\n sessionId: string,\n pageUrl: string,\n ): void {\n this.activeRenderers.add(renderer);\n this.activeByGuideId.set(guide.guideId, renderer);\n\n const onClose = (): void => {\n renderer.destroy();\n this.activeRenderers.delete(renderer);\n if (this.activeByGuideId.get(guide.guideId) === renderer) {\n this.activeByGuideId.delete(guide.guideId);\n }\n };\n\n const onInteraction = (event: GuideInteractionEvent): void => {\n this.handleInteraction(guide, sessionId, pageUrl, event);\n };\n\n const onTrack = (eventName: string, properties?: Record<string, unknown>): void => {\n this.client.track(eventName, properties);\n };\n\n const onFormSubmit = (answers: Record<string, unknown>): Promise<boolean> =>\n this.submitFormResponse(guide.guideId, answers);\n\n try {\n void renderer.render({ guide, onInteraction, onClose, onTrack, onFormSubmit });\n } catch (err) {\n if (this.debug) console.error('[veo] renderer.render threw:', err);\n this.activeRenderers.delete(renderer);\n if (this.activeByGuideId.get(guide.guideId) === renderer) {\n this.activeByGuideId.delete(guide.guideId);\n }\n }\n }\n\n /**\n * Si hay un walkthrough persistido, intenta pintar el step actual en\n * la página actual. Retorna `true` si lo intentó (sea éxito o cancel),\n * `false` si no había walkthrough activo.\n *\n * Cancela limpiamente (sin enviar `dismissed` falso) cuando:\n * - La guía fue eliminada en el backend (404 → `fetchById` devuelve null).\n * - La guía cambió de tipo y ya no es walkthrough.\n * - El selector del step actual no aparece dentro del timeout.\n */\n private async tryResumeWalkthrough(\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<boolean> {\n const state = this.walkthroughState.current();\n if (!state) return false;\n\n const guide = await this.resolver.fetchById(state.guideId);\n if (!guide || guide.guideType !== 'walkthrough') {\n if (this.debug)\n console.log(`[veo] guides: walkthrough ${state.guideId} no longer available, cleaning up`);\n this.tearDownWalkthrough();\n return true;\n }\n\n // El cache local podría tener una versión más vieja del total; usamos\n // siempre el del backend.\n const stepIndex = Math.min(state.currentStepIndex, guide.guideSteps.length - 1);\n await this.renderWalkthroughStep(guide, stepIndex, endUserId, sessionId, pageUrl);\n return true;\n }\n\n private async startWalkthrough(\n guide: ResolvedGuide,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<void> {\n this.walkthroughState.start(guide.guideId, guide.guideSteps.length);\n const rendered = await this.renderWalkthroughStep(guide, 0, endUserId, sessionId, pageUrl);\n if (!rendered) return; // teardown ya corrió, no reportamos shown.\n // Reportamos `shown` SOLO al arrancar (step 0). Steps siguientes\n // se cubren con `step_advanced`/`step_back`. Marcamos cache local\n // también para que `displayFrequency='once'` filtre en la próxima\n // pageview aunque la interaction aún esté en la queue.\n this.enqueueInteractionOnce(guide.guideId, endUserId, sessionId, pageUrl, 'shown', 0);\n this.frequencyCache.record(guide.guideId, 'shown');\n }\n\n /**\n * Pinta el step indicado. Reusa la guía (no fetcha): el caller debe\n * traerla. Retorna `true` si el render fue exitoso. En caso contrario\n * ya disparó el teardown — el caller no debe seguir reportando.\n */\n private async renderWalkthroughStep(\n guide: ResolvedGuide,\n stepIndex: number,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<boolean> {\n if (this.activeWalkthroughRenderer) {\n this.activeWalkthroughRenderer.destroy();\n this.activeWalkthroughRenderer = null;\n }\n\n const renderer = new WalkthroughRenderer();\n this.activeWalkthroughGuide = guide;\n\n const callbacks: WalkthroughCallbacks = {\n onNext: () => this.handleWalkthroughNext(endUserId, sessionId, pageUrl),\n onBack: () => this.handleWalkthroughBack(endUserId, sessionId, pageUrl),\n onSkip: () => this.handleWalkthroughSkip(endUserId, sessionId, pageUrl),\n onComplete: () => this.handleWalkthroughComplete(endUserId, sessionId, pageUrl),\n };\n\n let success = false;\n try {\n success = await renderer.render({ guide, currentStepIndex: stepIndex, callbacks });\n } catch (err) {\n if (this.debug) console.error('[veo] walkthrough renderer threw:', err);\n }\n\n if (!success) {\n if (this.debug)\n console.warn(\n `[veo] walkthrough ${guide.guideId} step ${stepIndex} could not render, cancelling`,\n );\n this.tearDownWalkthrough();\n return false;\n }\n\n this.activeWalkthroughRenderer = renderer;\n return true;\n }\n\n private handleWalkthroughNext(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n if (!guide) return;\n\n const newState = this.walkthroughState.advance();\n if (!newState) {\n // Ya estábamos en el último step. No debería pasar (el botón\n // dispara onComplete en ese caso), pero por defensa lo manejamos.\n this.handleWalkthroughComplete(endUserId, sessionId, pageUrl);\n return;\n }\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'step_advanced',\n newState.currentStepIndex,\n );\n void this.renderWalkthroughStep(\n guide,\n newState.currentStepIndex,\n endUserId,\n sessionId,\n pageUrl,\n );\n }\n\n private handleWalkthroughBack(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n if (!guide) return;\n\n const state = this.walkthroughState.current();\n if (!state || state.currentStepIndex === 0) return;\n\n const newState = this.walkthroughState.back();\n if (!newState) return;\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'step_back',\n newState.currentStepIndex,\n );\n void this.renderWalkthroughStep(\n guide,\n newState.currentStepIndex,\n endUserId,\n sessionId,\n pageUrl,\n );\n }\n\n private handleWalkthroughSkip(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n const state = this.walkthroughState.current();\n if (!guide || !state) return;\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'dismissed',\n state.currentStepIndex,\n );\n this.frequencyCache.record(guide.guideId, 'dismissed');\n this.tearDownWalkthrough();\n }\n\n private handleWalkthroughComplete(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n const state = this.walkthroughState.current();\n if (!guide || !state) return;\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'completed',\n state.currentStepIndex,\n );\n this.frequencyCache.record(guide.guideId, 'completed');\n this.tearDownWalkthrough();\n }\n\n private tearDownWalkthrough(): void {\n if (this.activeWalkthroughRenderer) {\n try {\n this.activeWalkthroughRenderer.destroy();\n } catch {\n // swallow\n }\n }\n this.activeWalkthroughRenderer = null;\n this.activeWalkthroughGuide = null;\n this.walkthroughState.clear();\n }\n\n /**\n * Tras cada interaction single-step:\n * 1. dedupe (no enviar 2× la misma `(guideId, action)` por sesión)\n * 2. actualizar el cache local si corresponde\n * 3. encolar el POST\n *\n * El endUserId se lee del client EN ESTE MOMENTO (no en el render),\n * por si el usuario se identificó después de que la guía apareció.\n */\n private handleInteraction(\n guide: ResolvedGuide,\n sessionId: string,\n pageUrl: string,\n event: GuideInteractionEvent,\n ): void {\n const dedupKey = `${guide.guideId}:${event.action}`;\n if (this.dispatched.has(dedupKey)) {\n if (this.debug) console.log(`[veo] guides: dedup hit ${dedupKey}`);\n return;\n }\n this.dispatched.add(dedupKey);\n\n const cacheStatus = STATUS_BY_ACTION[event.action];\n if (cacheStatus) this.frequencyCache.record(guide.guideId, cacheStatus);\n\n const endUserId = this.client.getEndUserId();\n if (!endUserId) {\n if (this.debug)\n console.warn('[veo] guides: interaction without endUserId — skipping enqueue');\n return;\n }\n\n this.trackerQueue.enqueue({\n guideId: guide.guideId,\n payload: {\n endUserId,\n sessionId,\n action: event.action,\n stepIndex: event.stepIndex,\n pageUrl,\n pagePath: extractPath(pageUrl),\n },\n });\n }\n\n /**\n * Encola una interacción de walkthrough SIN pasar por el dedup set.\n * Acciones como `step_advanced` se repiten naturalmente (cada next es\n * una navegación distinta) y deduplicarlas perdería datos.\n */\n private enqueueInteraction(\n guideId: string,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n action: GuideInteractionAction,\n stepIndex: number,\n ): void {\n this.trackerQueue.enqueue({\n guideId,\n payload: {\n endUserId,\n sessionId,\n action,\n stepIndex,\n pageUrl,\n pagePath: extractPath(pageUrl),\n },\n });\n }\n\n /**\n * Encola con dedup por sesión del SDK. Para `shown` del primer step:\n * no queremos re-emitirlo si el usuario navega entre dos páginas que\n * matchean el mismo step.\n */\n private enqueueInteractionOnce(\n guideId: string,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n action: GuideInteractionAction,\n stepIndex: number,\n ): void {\n const dedupKey = `${guideId}:${action}:${stepIndex}`;\n if (this.dispatched.has(dedupKey)) return;\n this.dispatched.add(dedupKey);\n this.enqueueInteraction(guideId, endUserId, sessionId, pageUrl, action, stepIndex);\n }\n\n private createSingleStepRenderer(type: GuideType): BaseRenderer | null {\n switch (type) {\n case 'modal':\n return new ModalRenderer();\n case 'banner':\n return new BannerRenderer();\n case 'tooltip':\n return new TooltipRenderer();\n case 'custom':\n return new CustomRenderer();\n case 'inline':\n return new InlineRenderer();\n case 'inline-custom':\n return new InlineCustomRenderer();\n case 'form':\n return new FormRenderer();\n case 'inline-form':\n return new InlineFormRenderer();\n case 'walkthrough':\n return null;\n }\n }\n\n /**\n * Envía las respuestas de una guía `form` al backend, que las mergea como\n * propiedades del usuario. Usa el endUserId actual (o el anónimo si aún no\n * hubo identify — el backend pre-crea la fila igual que identify).\n */\n private async submitFormResponse(\n guideId: string,\n answers: Record<string, unknown>,\n ): Promise<boolean> {\n const endUserId = this.client.getEndUserId() ?? this.client.getAnonymousId();\n try {\n const res = await fetch(`${this.apiUrl}/v1/guides/${guideId}/form-response`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': this.apiKey },\n body: JSON.stringify({ endUserId, answers }),\n });\n if (!res.ok && this.debug) {\n console.warn('[veo] form-response respondió', res.status);\n }\n return res.ok;\n } catch (err) {\n if (this.debug) console.warn('[veo] form-response falló:', err);\n return false;\n }\n }\n}\n\nfunction extractPath(url: string): string {\n try {\n return new URL(url).pathname;\n } catch {\n return '/';\n }\n}\n","import type { VeoPlugin } from '../../types';\nimport { hasWindow } from '../../utils/safe-env';\nimport { definePlugin } from '../plugin';\nimport { GuidesController } from './guides-controller';\n\nexport interface GuidesPluginConfig {\n apiUrl: string;\n apiKey: string;\n debug?: boolean;\n}\n\n/** Resultado del install — expone el controller para debugging desde el demo. */\nexport interface GuidesPluginHandle {\n controller: GuidesController;\n}\n\n/**\n * Plugin que renderiza guías in-app (modal/banner/tooltip) consultando\n * `GET /v1/guides/resolve` y registra las interacciones en\n * `POST /v1/guides/:id/interactions` vía queue dedicada con retry y\n * sendBeacon en pagehide.\n *\n * Opt-in: `init({ ..., guides: true })`. El plugin escucha\n * `pageview` e `identify` del client; el payload del evento ya trae\n * `sessionId` y `endUserId` para que no necesitemos consultar al\n * client en cada disparo.\n *\n * Frequency híbrida: el backend filtra autoritariamente; el cache\n * local (`GuideFrequencyCache`) solo previene el flash visual cuando\n * la interaction aún no se persistió.\n */\nexport function guidesPlugin(config: GuidesPluginConfig): VeoPlugin {\n return definePlugin({\n name: 'guides',\n install(client) {\n if (!hasWindow()) return;\n const controller = new GuidesController(client, config);\n\n // Exponer el controller en window para que el demo y tests E2E\n // puedan inspeccionar el cache y la queue.\n (window as unknown as { __veoGuides?: GuidesPluginHandle }).__veoGuides = { controller };\n\n client.on('identify', ({ sessionId }) => {\n void controller.checkGuides(window.location.href, sessionId);\n });\n\n client.on('pageview', ({ url, sessionId }) => {\n void controller.checkGuides(url, sessionId);\n });\n\n // Como el bundle de guías se carga PEREZOSAMENTE, el plugin puede\n // instalarse DESPUÉS del pageview/identify inicial — esos eventos ya\n // pasaron. Chequeamos la página actual ahora mismo para que la guía\n // aparezca apenas se entra (sin necesitar una 2ª acción). Si todavía no\n // hay endUserId, checkGuides no hace nada y el listener de `identify` la\n // mostrará; el dedupe por guideId evita un doble render.\n void controller.checkGuides(window.location.href, client.getSessionId());\n },\n });\n}\n\nexport type { PreviewGuideInput, PreviewHandle, PreviewResult } from './guide-preview';\nexport { closeGuidePreview, previewGuide } from './guide-preview';\nexport type { PreviewModeHandle, PreviewModeOptions } from './preview-mode';\nexport { runPreviewMode } from './preview-mode';\nexport type { GuideInteractionEvent, GuideStep, ResolvedGuide } from './types';\n"]}
1
+ {"version":3,"sources":["../src/plugins/plugin.ts","../src/plugins/guides/preview-mode.ts","../src/plugins/guides/guide-frequency-cache.ts","../src/plugins/guides/guide-resolver-client.ts","../src/plugins/guides/guide-tracker-client.ts","../src/plugins/guides/guide-tracker-queue.ts","../src/plugins/guides/walkthrough-state.ts","../src/plugins/guides/guides-controller.ts","../src/plugins/guides/index.ts"],"names":[],"mappings":"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","file":"chunk-B5GO6PTO.mjs","sourcesContent":["import type { VeoPlugin } from '../types';\n\n/**\n * Helper de identidad para definir un plugin con inferencia de tipos.\n * No transforma nada; mejora la ergonomía y deja un punto de extensión futuro.\n */\nexport function definePlugin(plugin: VeoPlugin): VeoPlugin {\n return plugin;\n}\n","/**\n * Modo PREVIEW POR LINK: la app del cliente se abre con\n * `?veoPreview=<token>` (link generado desde el dashboard) y el SDK canjea\n * el token contra `POST /v1/guides/preview-resolve` para renderizar ESA\n * guía como vista previa — aunque esté en draft — sobre la app real.\n *\n * A diferencia del modo builder no hay puente postMessage ni dashboard\n * abierto: es un link compartible para que el equipo pruebe la guía sin\n * publicarla. Reusa `previewGuide` (sin tracking/frecuencia/resolver) y\n * monta un chip flotante con \"volver a mostrar\" y \"cerrar\".\n *\n * Vive en el bundle de guías (`veo-guides.js`), NO en el `veo.js` core —\n * el core solo detecta el query param y dispara la carga del bundle.\n */\nimport { hasDocument } from '../../utils/safe-env';\nimport { previewGuide } from './guide-preview';\nimport type { ResolvedGuide } from './types';\n\nexport interface PreviewModeOptions {\n apiKey: string;\n apiUrl: string;\n /** Token firmado del link (`?veoPreview=<token>`). */\n token: string;\n debug?: boolean;\n}\n\nexport interface PreviewModeHandle {\n /** Cierra la preview y quita el chip. Idempotente. */\n teardown(): void;\n}\n\nlet active: PreviewModeHandle | null = null;\n\n/**\n * Canjea el token y renderiza la guía como vista previa + chip de control.\n * Si el token es inválido/expirado, el chip lo informa (solo quien tiene el\n * link lo ve). Solo una sesión de preview activa a la vez.\n */\nexport async function runPreviewMode(opts: PreviewModeOptions): Promise<PreviewModeHandle | null> {\n if (!hasDocument()) return null;\n active?.teardown();\n\n let guide: ResolvedGuide | null = null;\n try {\n const res = await fetch(`${opts.apiUrl}/v1/guides/preview-resolve`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': opts.apiKey },\n body: JSON.stringify({ token: opts.token }),\n });\n if (res.ok) {\n const data = (await res.json()) as { guide?: ResolvedGuide };\n guide = data.guide ?? null;\n } else if (opts.debug) {\n console.warn('[veo] preview-resolve respondió', res.status);\n }\n } catch (err) {\n if (opts.debug) console.warn('[veo] preview-resolve falló:', err);\n }\n\n /**\n * En el link de preview el envío de forms es REAL: corre sobre la app del\n * cliente con el SDK inicializado, así que la respuesta se guarda en el\n * usuario que está probando (su propia identidad) — permite verificar el\n * flujo completo props→segmentos sin tocar a nadie más.\n */\n const submitToBackend = async (answers: Record<string, unknown>): Promise<boolean> => {\n if (!guide) return false;\n const veo = (\n window as unknown as {\n veo?: { getEndUserId?: () => string | null; getAnonymousId?: () => string };\n }\n ).veo;\n const endUserId = veo?.getEndUserId?.() ?? veo?.getAnonymousId?.() ?? null;\n if (!endUserId) return false;\n try {\n const res = await fetch(`${opts.apiUrl}/v1/guides/${guide.guideId}/form-response`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': opts.apiKey },\n body: JSON.stringify({ endUserId, answers }),\n });\n return res.ok;\n } catch {\n return false;\n }\n };\n\n let preview: { close(): void } | null = null;\n const show = (): void => {\n if (!guide) return;\n preview?.close();\n preview = previewGuide({\n guideType: guide.guideType,\n guideSteps: guide.guideSteps,\n activationRules: guide.activationRules,\n guideName: guide.guideName,\n formSubmit: submitToBackend,\n formSubmitNote: 'Vista previa: guardado en TU usuario para probar el flujo.',\n });\n };\n\n const chip = mountChip({\n label: guide ? `Vista previa: ${guide.guideName}` : 'Link de preview inválido o vencido',\n error: !guide,\n onReshow: guide ? show : null,\n onClose: () => handle.teardown(),\n });\n\n const handle: PreviewModeHandle = {\n teardown() {\n preview?.close();\n preview = null;\n chip.remove();\n if (active === handle) active = null;\n },\n };\n active = handle;\n show();\n return handle;\n}\n\ninterface ChipOptions {\n label: string;\n error: boolean;\n onReshow: (() => void) | null;\n onClose: () => void;\n}\n\n/** Chip flotante (Shadow DOM, abajo-derecha) con re-mostrar y cerrar. */\nfunction mountChip(opts: ChipOptions): { remove(): void } {\n const host = document.createElement('div');\n host.setAttribute('data-veo-preview-chip', '');\n const root = host.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = `\n .chip { position: fixed; bottom: 16px; right: 16px; z-index: 2147483647;\n display: flex; align-items: center; gap: 8px; padding: 8px 12px;\n background: #111827; color: #f9fafb; border-radius: 9999px;\n font: 500 12px/1.2 system-ui, sans-serif; box-shadow: 0 4px 12px rgba(0,0,0,.25); }\n .chip.error { background: #7f1d1d; }\n .label { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n button { all: unset; cursor: pointer; padding: 2px 6px; border-radius: 9999px;\n font-size: 12px; line-height: 1; }\n button:hover { background: rgba(255,255,255,.15); }\n `;\n root.appendChild(style);\n\n const chip = document.createElement('div');\n chip.className = opts.error ? 'chip error' : 'chip';\n\n const label = document.createElement('span');\n label.className = 'label';\n label.textContent = opts.label;\n chip.appendChild(label);\n\n if (opts.onReshow) {\n const reshow = document.createElement('button');\n reshow.textContent = '↻';\n reshow.title = 'Volver a mostrar la guía';\n reshow.addEventListener('click', opts.onReshow);\n chip.appendChild(reshow);\n }\n\n const close = document.createElement('button');\n close.textContent = '✕';\n close.title = 'Salir de la vista previa';\n close.addEventListener('click', opts.onClose);\n chip.appendChild(close);\n\n root.appendChild(chip);\n document.body.appendChild(host);\n return { remove: () => host.remove() };\n}\n","import {\n FREQUENCY_CACHE_KEY_PREFIX,\n FREQUENCY_CACHE_MAX_ENTRIES,\n FREQUENCY_CACHE_TTL_MS,\n} from './constants';\nimport type { DisplayFrequency, FrequencyCacheEntry, FrequencyStatus } from './types';\n\n/** Prioridad de status para no degradar shown→dismissed→… */\nconst STATUS_PRIORITY: Record<FrequencyStatus, number> = {\n shown: 1,\n dismissed: 2,\n completed: 2,\n};\n\n/**\n * Namespace short y estable derivado del apiKey. NO es cripto: solo evita\n * que dos apps que comparten el navegador pisen sus caches. El apiKey\n * público (`pk_*`) ya es workspace-único, así que usar sus últimos 16\n * caracteres alcanza para diferenciar.\n */\nexport function namespaceFromApiKey(apiKey: string): string {\n return apiKey.slice(-16) || 'default';\n}\n\n/**\n * Cache persistente de \"qué guías ya vio/cerró este usuario\". Vive en\n * `localStorage` con key namespaceada para evitar colisión entre\n * workspaces que corren en el mismo navegador.\n *\n * No es source of truth — el backend siempre manda. Esta cache solo\n * evita el flash visual de re-pintar una guía que el usuario ya cerró\n * antes de que el roundtrip al backend termine.\n */\nexport class GuideFrequencyCache {\n private readonly storageKey: string;\n private cache: Map<string, FrequencyCacheEntry>;\n\n constructor(namespace: string) {\n this.storageKey = `${FREQUENCY_CACHE_KEY_PREFIX}${namespace}`;\n this.cache = this.load();\n this.prune();\n }\n\n /**\n * Decide si una guía debe filtrarse localmente antes de pintarla.\n *\n * - `every_visit` / `always` → nunca filtra (siempre re-pinta).\n * - `once` → cualquier entry registrada filtra (verla ya cuenta).\n * - `until_dismissed` → si fue descartada O COMPLETADA (responder un\n * form / terminar un walkthrough es más fuerte que descartar — sin\n * esto, una encuesta seguiría preguntando después de respondida).\n */\n shouldFilter(guideId: string, displayFrequency: DisplayFrequency): boolean {\n if (displayFrequency === 'every_visit' || displayFrequency === 'always') return false;\n\n const entry = this.cache.get(guideId);\n if (!entry) return false;\n\n if (displayFrequency === 'once') return true;\n if (displayFrequency === 'until_dismissed') {\n return entry.status === 'dismissed' || entry.status === 'completed';\n }\n // `until_answered` (forms): solo COMPLETAR filtra localmente. El descarte\n // no la silencia — y si las props ya tienen valor por otro medio, es el\n // BACKEND quien la excluye del resolve (acá no conocemos los traits).\n if (displayFrequency === 'until_answered') return entry.status === 'completed';\n return false;\n }\n\n /**\n * Registra/actualiza la entry de una guía. Nunca degrada un estado más\n * fuerte (no convierte `dismissed` en `shown` por un re-render). Persiste\n * cada llamada — escribir a localStorage es lo bastante barato.\n */\n record(guideId: string, status: FrequencyStatus): void {\n const existing = this.cache.get(guideId);\n if (existing && STATUS_PRIORITY[status] < STATUS_PRIORITY[existing.status]) {\n return;\n }\n this.cache.set(guideId, {\n guideId,\n status,\n lastInteractionAt: Date.now(),\n });\n this.persist();\n }\n\n /** Limpia el cache (botón \"reset\" del demo, tests). */\n clear(): void {\n this.cache.clear();\n this.persist();\n }\n\n /** Útil para debugging — devuelve un snapshot. */\n snapshot(): FrequencyCacheEntry[] {\n return Array.from(this.cache.values());\n }\n\n /**\n * Limpia entries expiradas por TTL y, si aún excede el límite, descarta\n * las más viejas hasta caber. Se ejecuta una vez en el constructor; no\n * vale la pena correrlo a cada lectura.\n */\n private prune(): void {\n const now = Date.now();\n let mutated = false;\n\n for (const [id, entry] of this.cache) {\n if (now - entry.lastInteractionAt > FREQUENCY_CACHE_TTL_MS) {\n this.cache.delete(id);\n mutated = true;\n }\n }\n\n if (this.cache.size > FREQUENCY_CACHE_MAX_ENTRIES) {\n const sorted = Array.from(this.cache.entries()).sort(\n (a, b) => a[1].lastInteractionAt - b[1].lastInteractionAt,\n );\n const excess = this.cache.size - FREQUENCY_CACHE_MAX_ENTRIES;\n for (let i = 0; i < excess; i++) {\n const tuple = sorted[i];\n if (tuple) this.cache.delete(tuple[0]);\n }\n mutated = true;\n }\n\n if (mutated) this.persist();\n }\n\n private load(): Map<string, FrequencyCacheEntry> {\n if (typeof localStorage === 'undefined') return new Map();\n try {\n const raw = localStorage.getItem(this.storageKey);\n if (!raw) return new Map();\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed)) return new Map();\n const entries: Array<[string, FrequencyCacheEntry]> = [];\n for (const item of parsed) {\n if (\n item &&\n typeof item === 'object' &&\n typeof (item as FrequencyCacheEntry).guideId === 'string' &&\n typeof (item as FrequencyCacheEntry).lastInteractionAt === 'number' &&\n ['shown', 'dismissed', 'completed'].includes((item as FrequencyCacheEntry).status)\n ) {\n const e = item as FrequencyCacheEntry;\n entries.push([e.guideId, e]);\n }\n }\n return new Map(entries);\n } catch {\n return new Map();\n }\n }\n\n private persist(): void {\n if (typeof localStorage === 'undefined') return;\n try {\n const serialized = JSON.stringify(Array.from(this.cache.values()));\n localStorage.setItem(this.storageKey, serialized);\n } catch {\n // QuotaExceeded o similar — el cache es opcional, no rompemos la app.\n }\n }\n}\n","import type { ResolvedGuide, ResolveGuidesResponse } from './types';\n\n/**\n * Wrapper sobre `GET /v1/guides/resolve`. Nunca lanza: cualquier error de\n * red o de parsing devuelve un array vacío, para que el plugin no rompa\n * la app del cliente.\n *\n * Importante: el endpoint usa `?pageUrl=...` (no `?url=...`) — el backend\n * valida con class-validator `IsUrl({ require_protocol: true })`.\n */\nexport class GuideResolverClient {\n constructor(\n private readonly apiUrl: string,\n private readonly apiKey: string,\n private readonly debug = false,\n ) {}\n\n async resolve(endUserId: string, pageUrl: string): Promise<ResolvedGuide[]> {\n const params = new URLSearchParams({ endUserId, pageUrl });\n let response: Response;\n try {\n response = await fetch(`${this.apiUrl}/v1/guides/resolve?${params.toString()}`, {\n method: 'GET',\n headers: { 'X-Api-Key': this.apiKey },\n credentials: 'omit',\n });\n } catch (err) {\n if (this.debug) console.error('[veo] guides resolve fetch failed:', err);\n return [];\n }\n\n if (!response.ok) {\n if (this.debug) console.warn('[veo] guides resolve HTTP', response.status);\n return [];\n }\n\n try {\n const data = (await response.json()) as ResolveGuidesResponse;\n return Array.isArray(data.guides) ? data.guides : [];\n } catch (err) {\n if (this.debug) console.error('[veo] guides resolve parse failed:', err);\n return [];\n }\n }\n\n /**\n * Trae una guía específica por ID, sin pasar por la lógica de\n * activación. La usa el controller para resumir un walkthrough entre\n * páginas: el `resolve` no devuelve la guía si la URL actual no\n * matchea, pero el walkthrough activo debe poder consultarla igual.\n *\n * El endpoint backend (`GET /v1/guides/:guideId`) devuelve `GuideResponse`,\n * un superset de `ResolvedGuide` con campos de audit. Acá descartamos los\n * extra y nos quedamos con el shape que el resto del SDK ya consume.\n *\n * Devuelve `null` en cualquier error (404, red, parse) — el caller debe\n * tratarlo como \"guía ya no existe\" y cancelar el walkthrough limpiamente.\n */\n async fetchById(guideId: string): Promise<ResolvedGuide | null> {\n let response: Response;\n try {\n response = await fetch(`${this.apiUrl}/v1/guides/${encodeURIComponent(guideId)}`, {\n method: 'GET',\n headers: { 'X-Api-Key': this.apiKey },\n credentials: 'omit',\n });\n } catch (err) {\n if (this.debug) console.error('[veo] guides fetchById network failed:', err);\n return null;\n }\n\n if (!response.ok) {\n if (this.debug) console.warn('[veo] guides fetchById HTTP', response.status);\n return null;\n }\n\n try {\n const data = (await response.json()) as Partial<ResolvedGuide>;\n if (\n typeof data.guideId !== 'string' ||\n typeof data.guideName !== 'string' ||\n typeof data.guideType !== 'string' ||\n !Array.isArray(data.guideSteps) ||\n !data.activationRules ||\n typeof data.displayFrequency !== 'string' ||\n typeof data.displayPriority !== 'number'\n ) {\n if (this.debug) console.warn('[veo] guides fetchById: unexpected shape');\n return null;\n }\n return {\n guideId: data.guideId,\n guideName: data.guideName,\n guideType: data.guideType,\n guideSteps: data.guideSteps,\n activationRules: data.activationRules,\n displayFrequency: data.displayFrequency,\n displayPriority: data.displayPriority,\n };\n } catch (err) {\n if (this.debug) console.error('[veo] guides fetchById parse failed:', err);\n return null;\n }\n }\n}\n","import type { GuideInteractionPayload } from './types';\n\nexport interface InteractionRequest {\n guideId: string;\n payload: GuideInteractionPayload;\n}\n\n/**\n * Wire shape esperada por `POST /v1/guides/:id/interactions` en el backend.\n * Nuestro tipo interno (`GuideInteractionPayload`) usa `action`/`stepIndex`;\n * el backend exige `interactionType`/`stepPosition`. Esta función centraliza\n * la traducción.\n */\ninterface WireInteraction {\n endUserId: string;\n sessionId?: string;\n interactionType: GuideInteractionPayload['action'];\n stepPosition?: number;\n pageUrl?: string;\n pagePath?: string;\n}\n\nfunction toWire(payload: GuideInteractionPayload): WireInteraction {\n const wire: WireInteraction = {\n endUserId: payload.endUserId,\n interactionType: payload.action,\n };\n if (payload.sessionId) wire.sessionId = payload.sessionId;\n if (typeof payload.stepIndex === 'number') wire.stepPosition = payload.stepIndex;\n if (payload.pageUrl) wire.pageUrl = payload.pageUrl;\n if (payload.pagePath) wire.pagePath = payload.pagePath;\n return wire;\n}\n\n/**\n * Cliente HTTP puro para registrar interacciones de guías. No hace retry\n * ni queue — esa responsabilidad vive en `GuideTrackerQueue`.\n *\n * `send` lanza en error (queue puede reintentar). `sendBeacon` es síncrono,\n * \"best effort\", para el cierre de página: usa `navigator.sendBeacon` con\n * el apiKey como query param `?key=` (la única forma de autenticar con\n * sendBeacon, ya que no permite headers custom — el backend lo soporta\n * desde el ApiKeyGuard).\n */\nexport class GuideTrackerClient {\n constructor(\n private readonly apiUrl: string,\n private readonly apiKey: string,\n ) {}\n\n async send(request: InteractionRequest): Promise<void> {\n const url = this.buildUrl(request.guideId);\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'X-Api-Key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(toWire(request.payload)),\n credentials: 'omit',\n });\n\n if (!response.ok) {\n throw new Error(`guide interaction send failed: HTTP ${response.status}`);\n }\n }\n\n /**\n * Envío \"fire-and-forget\" en pagehide. Devuelve `false` si el navegador\n * no acepta el beacon (cola llena, no soportado) — en ese caso la queue\n * sabrá que perdió el envío.\n */\n sendBeacon(request: InteractionRequest): boolean {\n if (typeof navigator === 'undefined' || typeof navigator.sendBeacon !== 'function') {\n return false;\n }\n const url = `${this.buildUrl(request.guideId)}?key=${encodeURIComponent(this.apiKey)}`;\n const blob = new Blob([JSON.stringify(toWire(request.payload))], {\n type: 'application/json',\n });\n try {\n return navigator.sendBeacon(url, blob);\n } catch {\n return false;\n }\n }\n\n private buildUrl(guideId: string): string {\n return `${this.apiUrl}/v1/guides/${encodeURIComponent(guideId)}/interactions`;\n }\n}\n","import type { GuideTrackerClient, InteractionRequest } from './guide-tracker-client';\nimport type { QueuedInteraction } from './types';\n\nexport interface GuideTrackerQueueConfig {\n client: GuideTrackerClient;\n flushIntervalMs: number;\n batchSize: number;\n maxRetries: number;\n /**\n * Llamado cuando un item se descarta tras agotar `maxRetries`. El\n * plugin puede usarlo para `console.warn` en debug mode. Nunca debe\n * lanzar — si lo hace, se ignora silenciosamente.\n */\n onError?: (error: Error, item: QueuedInteraction) => void;\n}\n\n/**\n * Queue dedicada para `POST /v1/guides/:id/interactions`.\n *\n * Cada item es independiente (URL distinto por `guideId`), así que el\n * \"batch\" en realidad dispara N requests en paralelo. El `batchSize` es\n * el umbral para forzar un flush — no agrupa requests en uno solo.\n *\n * Retry:\n * - Si `send()` lanza, el item se devuelve al buffer con `attempts++`.\n * - El timer regular vuelve a intentar en el próximo tick.\n * - Al alcanzar `maxRetries`, se descarta llamando `onError`.\n *\n * En `pagehide`/`visibilitychange` (hidden) drena el buffer vía\n * `navigator.sendBeacon`. Best effort — no re-encola lo que el beacon\n * rechace porque la página ya se va.\n */\nexport class GuideTrackerQueue {\n private buffer: QueuedInteraction[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n private unloadCleanup: (() => void) | null = null;\n\n constructor(private readonly config: GuideTrackerQueueConfig) {\n this.startTimer();\n this.installUnloadHandler();\n }\n\n /** Tamaño actual del buffer (útil para debug/stats en el demo). */\n get size(): number {\n return this.buffer.length;\n }\n\n /**\n * Encola una interaction. Si el buffer alcanza `batchSize`, dispara\n * `flush()` inmediato.\n */\n enqueue(request: InteractionRequest): void {\n this.buffer.push({\n guideId: request.guideId,\n payload: request.payload,\n attempts: 0,\n enqueuedAt: Date.now(),\n });\n if (this.buffer.length >= this.config.batchSize) {\n void this.flush();\n }\n }\n\n /**\n * Envía todo el buffer en paralelo. Items que fallan vuelven al buffer\n * si todavía tienen reintentos disponibles. Idempotente con respecto a\n * flushes concurrentes (el segundo es un no-op).\n */\n async flush(): Promise<void> {\n if (this.flushing || this.buffer.length === 0) return;\n this.flushing = true;\n\n const batch = this.buffer.splice(0, this.buffer.length);\n const results = await Promise.allSettled(\n batch.map((item) =>\n this.config.client.send({ guideId: item.guideId, payload: item.payload }),\n ),\n );\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n const item = batch[i];\n if (!result || !item) continue;\n if (result.status === 'fulfilled') continue;\n\n item.attempts += 1;\n if (item.attempts < this.config.maxRetries) {\n this.buffer.push(item);\n } else {\n this.safeOnError(result.reason, item);\n }\n }\n\n this.flushing = false;\n }\n\n /**\n * Drena el buffer vía `sendBeacon`. Síncrono, sin retry. Para pagehide.\n */\n flushBeacon(): void {\n if (this.buffer.length === 0) return;\n const batch = this.buffer.splice(0, this.buffer.length);\n for (const item of batch) {\n this.config.client.sendBeacon({ guideId: item.guideId, payload: item.payload });\n }\n }\n\n destroy(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n this.unloadCleanup?.();\n this.unloadCleanup = null;\n }\n\n private startTimer(): void {\n if (typeof window === 'undefined') return;\n this.timer = setInterval(() => {\n void this.flush();\n }, this.config.flushIntervalMs);\n }\n\n private installUnloadHandler(): void {\n if (typeof window === 'undefined') return;\n const onPagehide = (): void => this.flushBeacon();\n const onVisibility = (): void => {\n if (document.visibilityState === 'hidden') this.flushBeacon();\n };\n window.addEventListener('pagehide', onPagehide);\n window.addEventListener('visibilitychange', onVisibility);\n this.unloadCleanup = () => {\n window.removeEventListener('pagehide', onPagehide);\n window.removeEventListener('visibilitychange', onVisibility);\n };\n }\n\n private safeOnError(reason: unknown, item: QueuedInteraction): void {\n if (!this.config.onError) return;\n const error = reason instanceof Error ? reason : new Error(String(reason));\n try {\n this.config.onError(error, item);\n } catch {\n // Un onError roto no debe afectar al resto del flush.\n }\n }\n}\n","import { WALKTHROUGH_ABANDONMENT_TIMEOUT_MS, WALKTHROUGH_STATE_KEY_PREFIX } from './constants';\nimport type { WalkthroughState } from './types';\n\n/**\n * Estado persistente del walkthrough activo. Solo permite UNO por\n * workspace (namespace de apiKey). Vive en `localStorage` para sobrevivir\n * recargas de página: el step actual + el guideId alcanzan para resumir\n * desde donde quedó el usuario.\n *\n * Si pasan más de `WALKTHROUGH_ABANDONMENT_TIMEOUT_MS` sin progreso, se\n * considera abandonado: la próxima llamada a `current()` lo limpia\n * silenciosamente. NO se reporta `dismissed` al backend en ese caso —\n * abandonarse no es un acto del usuario.\n */\nexport class WalkthroughStateManager {\n private readonly storageKey: string;\n private state: WalkthroughState | null = null;\n\n constructor(namespace: string) {\n this.storageKey = `${WALKTHROUGH_STATE_KEY_PREFIX}${namespace}`;\n this.state = this.load();\n if (this.state && this.isAbandoned(this.state)) {\n this.clear();\n }\n }\n\n /**\n * Estado del walkthrough activo. Devuelve `null` si no hay ninguno o si\n * el último progreso fue hace más del timeout (en ese caso también\n * limpia el storage como side-effect).\n */\n current(): WalkthroughState | null {\n if (!this.state) return null;\n if (this.isAbandoned(this.state)) {\n this.clear();\n return null;\n }\n return this.state;\n }\n\n /** Atajo legible para el controller. */\n hasActive(): boolean {\n return this.current() !== null;\n }\n\n /**\n * Inicia un nuevo walkthrough en step 0. Sobreescribe cualquier estado\n * previo — los callers (controller) son responsables de verificar\n * `hasActive()` antes si necesitan exclusividad.\n */\n start(guideId: string, totalSteps: number): WalkthroughState {\n const now = Date.now();\n this.state = {\n guideId,\n totalSteps,\n currentStepIndex: 0,\n startedAt: now,\n lastProgressAt: now,\n };\n this.persist();\n return this.state;\n }\n\n /**\n * Avanza al siguiente step. Si el step resultante excede `totalSteps`,\n * devuelve `null` y NO toca el estado — el controller debe interpretar\n * eso como \"ya estamos en el último, no hay próximo\" y disparar\n * `complete` vía el handler del botón \"Finalizar\".\n */\n advance(): WalkthroughState | null {\n if (!this.state) return null;\n\n const next = this.state.currentStepIndex + 1;\n if (next >= this.state.totalSteps) return null;\n\n this.state = {\n ...this.state,\n currentStepIndex: next,\n lastProgressAt: Date.now(),\n };\n this.persist();\n return this.state;\n }\n\n /**\n * Retrocede al step anterior. En step 0 no hace nada y devuelve el\n * estado tal cual (el botón \"Atrás\" no debería estar visible en el\n * primer step, pero por defensa el manager también lo guard-ea).\n */\n back(): WalkthroughState | null {\n if (!this.state) return null;\n if (this.state.currentStepIndex === 0) return this.state;\n\n this.state = {\n ...this.state,\n currentStepIndex: this.state.currentStepIndex - 1,\n lastProgressAt: Date.now(),\n };\n this.persist();\n return this.state;\n }\n\n /** Limpia el estado activo (skip, complete, abandono, guía borrada). */\n clear(): void {\n this.state = null;\n if (typeof localStorage === 'undefined') return;\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // Storage bloqueado — no rompemos la app.\n }\n }\n\n private isAbandoned(state: WalkthroughState): boolean {\n return Date.now() - state.lastProgressAt > WALKTHROUGH_ABANDONMENT_TIMEOUT_MS;\n }\n\n private load(): WalkthroughState | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(this.storageKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== 'object') return null;\n const candidate = parsed as Partial<WalkthroughState>;\n if (\n typeof candidate.guideId !== 'string' ||\n typeof candidate.totalSteps !== 'number' ||\n typeof candidate.currentStepIndex !== 'number' ||\n typeof candidate.startedAt !== 'number' ||\n typeof candidate.lastProgressAt !== 'number'\n ) {\n return null;\n }\n return candidate as WalkthroughState;\n } catch {\n return null;\n }\n }\n\n private persist(): void {\n if (typeof localStorage === 'undefined' || !this.state) return;\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(this.state));\n } catch {\n // Quota exceeded — silently fail. El walkthrough en memoria sigue.\n }\n }\n}\n","import type { VeoClient } from '../../types';\nimport {\n DEFAULT_TRACKER_BATCH_SIZE,\n DEFAULT_TRACKER_FLUSH_INTERVAL_MS,\n DEFAULT_TRACKER_MAX_RETRIES,\n} from './constants';\nimport { GuideFrequencyCache, namespaceFromApiKey } from './guide-frequency-cache';\nimport { GuideResolverClient } from './guide-resolver-client';\nimport { GuideTrackerClient } from './guide-tracker-client';\nimport { GuideTrackerQueue } from './guide-tracker-queue';\nimport { BannerRenderer } from './renderers/banner-renderer';\nimport type { BaseRenderer } from './renderers/base-renderer';\nimport { CustomRenderer } from './renderers/custom-renderer';\nimport { FormRenderer } from './renderers/form-renderer';\nimport { InlineCustomRenderer } from './renderers/inline-custom-renderer';\nimport { InlineFormRenderer } from './renderers/inline-form-renderer';\nimport { InlineRenderer } from './renderers/inline-renderer';\nimport { ModalRenderer } from './renderers/modal-renderer';\nimport { TooltipRenderer } from './renderers/tooltip-renderer';\nimport { WalkthroughRenderer } from './renderers/walkthrough-renderer';\nimport type {\n FrequencyStatus,\n GuideInteractionAction,\n GuideInteractionEvent,\n GuideType,\n ResolvedGuide,\n WalkthroughCallbacks,\n} from './types';\nimport { WalkthroughStateManager } from './walkthrough-state';\n\nexport interface GuidesControllerConfig {\n apiUrl: string;\n apiKey: string;\n debug?: boolean;\n /** Override del resolver (tests). */\n resolver?: GuideResolverClient;\n /** Override del tracker queue (tests). */\n trackerQueue?: GuideTrackerQueue;\n /** Override del cache (tests). */\n frequencyCache?: GuideFrequencyCache;\n /** Override del walkthrough state manager (tests). */\n walkthroughState?: WalkthroughStateManager;\n}\n\n/** Mapeo `action → cache status`. Solo acciones terminales mutan el cache. */\nconst STATUS_BY_ACTION: Record<GuideInteractionAction, FrequencyStatus | null> = {\n shown: 'shown',\n dismissed: 'dismissed',\n cta_clicked: null,\n step_advanced: null,\n step_back: null,\n completed: 'completed',\n};\n\n/**\n * Orquesta el ciclo de vida de las guías:\n *\n * 1. `pageview`/`identify` → `checkGuides(url, sessionId)`.\n * 2. Si hay un walkthrough activo (estado persistido en localStorage),\n * tiene prioridad: se intenta resumir en la página actual antes de\n * consultar nuevas guías. Si el selector del step actual aparece,\n * se pinta; si no, se cancela el walkthrough limpiamente.\n * 3. Si no hay walkthrough activo, se consulta `/v1/guides/resolve` y\n * se procesa cada guía:\n * - `walkthrough` con varios steps → arranca un walkthrough\n * (uno a la vez; el resto se ignora si ya hay uno).\n * - single-step → modal/banner/tooltip como antes.\n * 4. Cada interaction actualiza el cache local Y se encola para\n * `POST /v1/guides/:id/interactions`.\n *\n * Dedupe: `dispatched` guarda `${guideId}:${action}` ya encolados en la\n * sesión actual del SDK. Las acciones por-step de walkthroughs no\n * usan dedupe — cada `step_advanced` puede repetirse y representa una\n * navegación distinta.\n */\nexport class GuidesController {\n private readonly resolver: GuideResolverClient;\n private readonly trackerQueue: GuideTrackerQueue;\n private readonly frequencyCache: GuideFrequencyCache;\n private readonly walkthroughState: WalkthroughStateManager;\n private readonly debug: boolean;\n /** Para `POST /v1/guides/:id/form-response` (respuestas de guías form). */\n private readonly apiUrl: string;\n private readonly apiKey: string;\n private readonly activeRenderers = new Set<BaseRenderer>();\n /**\n * Guías single-step actualmente en pantalla, por `guideId`. Evita repintar/\n * duplicar la misma guía en cada pageview de una SPA (p.ej. una guía inline\n * anclada a un elemento persistente). Se libera al cerrarse la guía.\n */\n private readonly activeByGuideId = new Map<string, BaseRenderer>();\n private readonly dispatched = new Set<string>();\n private activeWalkthroughRenderer: WalkthroughRenderer | null = null;\n private activeWalkthroughGuide: ResolvedGuide | null = null;\n\n constructor(\n private readonly client: VeoClient,\n config: GuidesControllerConfig,\n ) {\n this.debug = config.debug === true;\n this.apiUrl = config.apiUrl;\n this.apiKey = config.apiKey;\n this.resolver =\n config.resolver ?? new GuideResolverClient(config.apiUrl, config.apiKey, this.debug);\n\n if (config.trackerQueue) {\n this.trackerQueue = config.trackerQueue;\n } else {\n const httpClient = new GuideTrackerClient(config.apiUrl, config.apiKey);\n this.trackerQueue = new GuideTrackerQueue({\n client: httpClient,\n flushIntervalMs: DEFAULT_TRACKER_FLUSH_INTERVAL_MS,\n batchSize: DEFAULT_TRACKER_BATCH_SIZE,\n maxRetries: DEFAULT_TRACKER_MAX_RETRIES,\n onError: (err, item) => {\n if (this.debug) {\n console.warn(\n `[veo] dropped guide interaction after retries: guideId=${item.guideId} action=${item.payload.action}`,\n err,\n );\n }\n },\n });\n }\n\n const namespace = namespaceFromApiKey(config.apiKey);\n this.frequencyCache = config.frequencyCache ?? new GuideFrequencyCache(namespace);\n this.walkthroughState = config.walkthroughState ?? new WalkthroughStateManager(namespace);\n }\n\n /** Cuántas interactions hay pendientes de envío. Útil para debug en demo. */\n get pendingInteractions(): number {\n return this.trackerQueue.size;\n }\n\n /** Limpia el cache local (botón \"reset\" del demo, tests). */\n clearFrequencyCache(): void {\n this.frequencyCache.clear();\n }\n\n /** Limpia el walkthrough activo (debug del demo). */\n clearWalkthroughState(): void {\n this.tearDownWalkthrough();\n }\n\n /** Punto de entrada principal. Llamado en cada pageview/identify. */\n async checkGuides(pageUrl: string, sessionId: string): Promise<void> {\n const endUserId = this.client.getEndUserId();\n if (!endUserId) {\n if (this.debug) console.log('[veo] guides: skipped, no endUserId yet');\n return;\n }\n\n if (await this.tryResumeWalkthrough(endUserId, sessionId, pageUrl)) {\n return;\n }\n\n let guides: ResolvedGuide[];\n try {\n guides = await this.resolver.resolve(endUserId, pageUrl);\n } catch (err) {\n if (this.debug) console.error('[veo] guides resolver threw:', err);\n return;\n }\n if (this.debug) console.log(`[veo] guides: ${guides.length} eligible at ${pageUrl}`);\n\n for (const guide of guides) {\n if (this.frequencyCache.shouldFilter(guide.guideId, guide.displayFrequency)) {\n if (this.debug) console.log(`[veo] guides: filtered locally guideId=${guide.guideId}`);\n continue;\n }\n\n // Ya está en pantalla → no repintar/duplicar (clave en SPAs: cada\n // navegación dispara un pageview, pero la guía sigue montada).\n if (this.activeByGuideId.has(guide.guideId)) {\n if (this.debug) console.log(`[veo] guides: already shown guideId=${guide.guideId}`);\n continue;\n }\n\n if (guide.guideType === 'walkthrough' && guide.guideSteps.length > 1) {\n if (this.walkthroughState.hasActive()) {\n if (this.debug)\n console.log(`[veo] guides: walkthrough ${guide.guideId} skipped (another active)`);\n continue;\n }\n await this.startWalkthrough(guide, endUserId, sessionId, pageUrl);\n // No retornamos: las guías single-step pueden seguir mostrándose\n // en paralelo. Solo bloqueamos OTROS walkthroughs vía hasActive().\n continue;\n }\n\n this.runSingleStepRender(guide, sessionId, pageUrl);\n }\n }\n\n /** Cierra todas las guías activas, limpia cache de dispatch y para timers. */\n destroy(): void {\n for (const renderer of this.activeRenderers) {\n try {\n renderer.destroy();\n } catch (err) {\n if (this.debug) console.error('[veo] renderer destroy failed:', err);\n }\n }\n this.activeRenderers.clear();\n this.activeByGuideId.clear();\n if (this.activeWalkthroughRenderer) {\n try {\n this.activeWalkthroughRenderer.destroy();\n } catch {\n // swallow — el cleanup no debe propagar\n }\n this.activeWalkthroughRenderer = null;\n this.activeWalkthroughGuide = null;\n }\n this.dispatched.clear();\n this.trackerQueue.destroy();\n }\n\n private runSingleStepRender(guide: ResolvedGuide, sessionId: string, pageUrl: string): void {\n const renderer = this.createSingleStepRenderer(guide.guideType);\n if (!renderer) return;\n\n // Reservar el slot YA (antes del delay) para que pageviews rápidos no\n // disparen dos renders de la misma guía.\n this.activeByGuideId.set(guide.guideId, renderer);\n\n const delayMs = guide.activationRules.delayMs ?? 0;\n window.setTimeout(\n () => this.mountSingleStepRenderer(guide, renderer, sessionId, pageUrl),\n delayMs,\n );\n }\n\n private mountSingleStepRenderer(\n guide: ResolvedGuide,\n renderer: BaseRenderer,\n sessionId: string,\n pageUrl: string,\n ): void {\n this.activeRenderers.add(renderer);\n this.activeByGuideId.set(guide.guideId, renderer);\n\n const onClose = (): void => {\n renderer.destroy();\n this.activeRenderers.delete(renderer);\n if (this.activeByGuideId.get(guide.guideId) === renderer) {\n this.activeByGuideId.delete(guide.guideId);\n }\n };\n\n const onInteraction = (event: GuideInteractionEvent): void => {\n this.handleInteraction(guide, sessionId, pageUrl, event);\n };\n\n const onTrack = (eventName: string, properties?: Record<string, unknown>): void => {\n this.client.track(eventName, properties);\n };\n\n const onFormSubmit = (answers: Record<string, unknown>): Promise<boolean> =>\n this.submitFormResponse(guide.guideId, answers);\n\n try {\n void renderer.render({ guide, onInteraction, onClose, onTrack, onFormSubmit });\n } catch (err) {\n if (this.debug) console.error('[veo] renderer.render threw:', err);\n this.activeRenderers.delete(renderer);\n if (this.activeByGuideId.get(guide.guideId) === renderer) {\n this.activeByGuideId.delete(guide.guideId);\n }\n }\n }\n\n /**\n * Si hay un walkthrough persistido, intenta pintar el step actual en\n * la página actual. Retorna `true` si lo intentó (sea éxito o cancel),\n * `false` si no había walkthrough activo.\n *\n * Cancela limpiamente (sin enviar `dismissed` falso) cuando:\n * - La guía fue eliminada en el backend (404 → `fetchById` devuelve null).\n * - La guía cambió de tipo y ya no es walkthrough.\n * - El selector del step actual no aparece dentro del timeout.\n */\n private async tryResumeWalkthrough(\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<boolean> {\n const state = this.walkthroughState.current();\n if (!state) return false;\n\n const guide = await this.resolver.fetchById(state.guideId);\n if (!guide || guide.guideType !== 'walkthrough') {\n if (this.debug)\n console.log(`[veo] guides: walkthrough ${state.guideId} no longer available, cleaning up`);\n this.tearDownWalkthrough();\n return true;\n }\n\n // El cache local podría tener una versión más vieja del total; usamos\n // siempre el del backend.\n const stepIndex = Math.min(state.currentStepIndex, guide.guideSteps.length - 1);\n await this.renderWalkthroughStep(guide, stepIndex, endUserId, sessionId, pageUrl);\n return true;\n }\n\n private async startWalkthrough(\n guide: ResolvedGuide,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<void> {\n this.walkthroughState.start(guide.guideId, guide.guideSteps.length);\n const rendered = await this.renderWalkthroughStep(guide, 0, endUserId, sessionId, pageUrl);\n if (!rendered) return; // teardown ya corrió, no reportamos shown.\n // Reportamos `shown` SOLO al arrancar (step 0). Steps siguientes\n // se cubren con `step_advanced`/`step_back`. Marcamos cache local\n // también para que `displayFrequency='once'` filtre en la próxima\n // pageview aunque la interaction aún esté en la queue.\n this.enqueueInteractionOnce(guide.guideId, endUserId, sessionId, pageUrl, 'shown', 0);\n this.frequencyCache.record(guide.guideId, 'shown');\n }\n\n /**\n * Pinta el step indicado. Reusa la guía (no fetcha): el caller debe\n * traerla. Retorna `true` si el render fue exitoso. En caso contrario\n * ya disparó el teardown — el caller no debe seguir reportando.\n */\n private async renderWalkthroughStep(\n guide: ResolvedGuide,\n stepIndex: number,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<boolean> {\n if (this.activeWalkthroughRenderer) {\n this.activeWalkthroughRenderer.destroy();\n this.activeWalkthroughRenderer = null;\n }\n\n const renderer = new WalkthroughRenderer();\n this.activeWalkthroughGuide = guide;\n\n const callbacks: WalkthroughCallbacks = {\n onNext: () => this.handleWalkthroughNext(endUserId, sessionId, pageUrl),\n onBack: () => this.handleWalkthroughBack(endUserId, sessionId, pageUrl),\n onSkip: () => this.handleWalkthroughSkip(endUserId, sessionId, pageUrl),\n onComplete: () => this.handleWalkthroughComplete(endUserId, sessionId, pageUrl),\n };\n\n let success = false;\n try {\n success = await renderer.render({ guide, currentStepIndex: stepIndex, callbacks });\n } catch (err) {\n if (this.debug) console.error('[veo] walkthrough renderer threw:', err);\n }\n\n if (!success) {\n if (this.debug)\n console.warn(\n `[veo] walkthrough ${guide.guideId} step ${stepIndex} could not render, cancelling`,\n );\n this.tearDownWalkthrough();\n return false;\n }\n\n this.activeWalkthroughRenderer = renderer;\n return true;\n }\n\n private handleWalkthroughNext(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n if (!guide) return;\n\n const newState = this.walkthroughState.advance();\n if (!newState) {\n // Ya estábamos en el último step. No debería pasar (el botón\n // dispara onComplete en ese caso), pero por defensa lo manejamos.\n this.handleWalkthroughComplete(endUserId, sessionId, pageUrl);\n return;\n }\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'step_advanced',\n newState.currentStepIndex,\n );\n void this.renderWalkthroughStep(\n guide,\n newState.currentStepIndex,\n endUserId,\n sessionId,\n pageUrl,\n );\n }\n\n private handleWalkthroughBack(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n if (!guide) return;\n\n const state = this.walkthroughState.current();\n if (!state || state.currentStepIndex === 0) return;\n\n const newState = this.walkthroughState.back();\n if (!newState) return;\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'step_back',\n newState.currentStepIndex,\n );\n void this.renderWalkthroughStep(\n guide,\n newState.currentStepIndex,\n endUserId,\n sessionId,\n pageUrl,\n );\n }\n\n private handleWalkthroughSkip(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n const state = this.walkthroughState.current();\n if (!guide || !state) return;\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'dismissed',\n state.currentStepIndex,\n );\n this.frequencyCache.record(guide.guideId, 'dismissed');\n this.tearDownWalkthrough();\n }\n\n private handleWalkthroughComplete(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n const state = this.walkthroughState.current();\n if (!guide || !state) return;\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'completed',\n state.currentStepIndex,\n );\n this.frequencyCache.record(guide.guideId, 'completed');\n this.tearDownWalkthrough();\n }\n\n private tearDownWalkthrough(): void {\n if (this.activeWalkthroughRenderer) {\n try {\n this.activeWalkthroughRenderer.destroy();\n } catch {\n // swallow\n }\n }\n this.activeWalkthroughRenderer = null;\n this.activeWalkthroughGuide = null;\n this.walkthroughState.clear();\n }\n\n /**\n * Tras cada interaction single-step:\n * 1. dedupe (no enviar 2× la misma `(guideId, action)` por sesión)\n * 2. actualizar el cache local si corresponde\n * 3. encolar el POST\n *\n * El endUserId se lee del client EN ESTE MOMENTO (no en el render),\n * por si el usuario se identificó después de que la guía apareció.\n */\n private handleInteraction(\n guide: ResolvedGuide,\n sessionId: string,\n pageUrl: string,\n event: GuideInteractionEvent,\n ): void {\n const dedupKey = `${guide.guideId}:${event.action}`;\n if (this.dispatched.has(dedupKey)) {\n if (this.debug) console.log(`[veo] guides: dedup hit ${dedupKey}`);\n return;\n }\n this.dispatched.add(dedupKey);\n\n const cacheStatus = STATUS_BY_ACTION[event.action];\n if (cacheStatus) this.frequencyCache.record(guide.guideId, cacheStatus);\n\n const endUserId = this.client.getEndUserId();\n if (!endUserId) {\n if (this.debug)\n console.warn('[veo] guides: interaction without endUserId — skipping enqueue');\n return;\n }\n\n this.trackerQueue.enqueue({\n guideId: guide.guideId,\n payload: {\n endUserId,\n sessionId,\n action: event.action,\n stepIndex: event.stepIndex,\n pageUrl,\n pagePath: extractPath(pageUrl),\n },\n });\n }\n\n /**\n * Encola una interacción de walkthrough SIN pasar por el dedup set.\n * Acciones como `step_advanced` se repiten naturalmente (cada next es\n * una navegación distinta) y deduplicarlas perdería datos.\n */\n private enqueueInteraction(\n guideId: string,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n action: GuideInteractionAction,\n stepIndex: number,\n ): void {\n this.trackerQueue.enqueue({\n guideId,\n payload: {\n endUserId,\n sessionId,\n action,\n stepIndex,\n pageUrl,\n pagePath: extractPath(pageUrl),\n },\n });\n }\n\n /**\n * Encola con dedup por sesión del SDK. Para `shown` del primer step:\n * no queremos re-emitirlo si el usuario navega entre dos páginas que\n * matchean el mismo step.\n */\n private enqueueInteractionOnce(\n guideId: string,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n action: GuideInteractionAction,\n stepIndex: number,\n ): void {\n const dedupKey = `${guideId}:${action}:${stepIndex}`;\n if (this.dispatched.has(dedupKey)) return;\n this.dispatched.add(dedupKey);\n this.enqueueInteraction(guideId, endUserId, sessionId, pageUrl, action, stepIndex);\n }\n\n private createSingleStepRenderer(type: GuideType): BaseRenderer | null {\n switch (type) {\n case 'modal':\n return new ModalRenderer();\n case 'banner':\n return new BannerRenderer();\n case 'tooltip':\n return new TooltipRenderer();\n case 'custom':\n return new CustomRenderer();\n case 'inline':\n return new InlineRenderer();\n case 'inline-custom':\n return new InlineCustomRenderer();\n case 'form':\n return new FormRenderer();\n case 'inline-form':\n return new InlineFormRenderer();\n case 'walkthrough':\n return null;\n }\n }\n\n /**\n * Envía las respuestas de una guía `form` al backend, que las mergea como\n * propiedades del usuario. Usa el endUserId actual (o el anónimo si aún no\n * hubo identify — el backend pre-crea la fila igual que identify).\n */\n private async submitFormResponse(\n guideId: string,\n answers: Record<string, unknown>,\n ): Promise<boolean> {\n const endUserId = this.client.getEndUserId() ?? this.client.getAnonymousId();\n try {\n const res = await fetch(`${this.apiUrl}/v1/guides/${guideId}/form-response`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': this.apiKey },\n body: JSON.stringify({ endUserId, answers }),\n });\n if (!res.ok && this.debug) {\n console.warn('[veo] form-response respondió', res.status);\n }\n return res.ok;\n } catch (err) {\n if (this.debug) console.warn('[veo] form-response falló:', err);\n return false;\n }\n }\n}\n\nfunction extractPath(url: string): string {\n try {\n return new URL(url).pathname;\n } catch {\n return '/';\n }\n}\n","import type { VeoPlugin } from '../../types';\nimport { hasWindow } from '../../utils/safe-env';\nimport { definePlugin } from '../plugin';\nimport { GuidesController } from './guides-controller';\n\nexport interface GuidesPluginConfig {\n apiUrl: string;\n apiKey: string;\n debug?: boolean;\n}\n\n/** Resultado del install — expone el controller para debugging desde el demo. */\nexport interface GuidesPluginHandle {\n controller: GuidesController;\n}\n\n/**\n * Plugin que renderiza guías in-app (modal/banner/tooltip) consultando\n * `GET /v1/guides/resolve` y registra las interacciones en\n * `POST /v1/guides/:id/interactions` vía queue dedicada con retry y\n * sendBeacon en pagehide.\n *\n * Opt-in: `init({ ..., guides: true })`. El plugin escucha\n * `pageview` e `identify` del client; el payload del evento ya trae\n * `sessionId` y `endUserId` para que no necesitemos consultar al\n * client en cada disparo.\n *\n * Frequency híbrida: el backend filtra autoritariamente; el cache\n * local (`GuideFrequencyCache`) solo previene el flash visual cuando\n * la interaction aún no se persistió.\n */\nexport function guidesPlugin(config: GuidesPluginConfig): VeoPlugin {\n return definePlugin({\n name: 'guides',\n install(client) {\n if (!hasWindow()) return;\n const controller = new GuidesController(client, config);\n\n // Exponer el controller en window para que el demo y tests E2E\n // puedan inspeccionar el cache y la queue.\n (window as unknown as { __veoGuides?: GuidesPluginHandle }).__veoGuides = { controller };\n\n client.on('identify', ({ sessionId }) => {\n void controller.checkGuides(window.location.href, sessionId);\n });\n\n client.on('pageview', ({ url, sessionId }) => {\n void controller.checkGuides(url, sessionId);\n });\n\n // Como el bundle de guías se carga PEREZOSAMENTE, el plugin puede\n // instalarse DESPUÉS del pageview/identify inicial — esos eventos ya\n // pasaron. Chequeamos la página actual ahora mismo para que la guía\n // aparezca apenas se entra (sin necesitar una 2ª acción). Si todavía no\n // hay endUserId, checkGuides no hace nada y el listener de `identify` la\n // mostrará; el dedupe por guideId evita un doble render.\n void controller.checkGuides(window.location.href, client.getSessionId());\n },\n });\n}\n\nexport type { PreviewGuideInput, PreviewHandle, PreviewResult } from './guide-preview';\nexport { closeGuidePreview, previewGuide } from './guide-preview';\nexport type { PreviewModeHandle, PreviewModeOptions } from './preview-mode';\nexport { runPreviewMode } from './preview-mode';\nexport type { GuideInteractionEvent, GuideStep, ResolvedGuide } from './types';\n"]}