veo-sdk 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{builder-PPLIAUCM.mjs → builder-5F2EFT4X.mjs} +4 -4
- package/dist/{builder-PPLIAUCM.mjs.map → builder-5F2EFT4X.mjs.map} +1 -1
- package/dist/builder.cjs +42 -11
- package/dist/builder.cjs.map +1 -1
- package/dist/builder.mjs +4 -4
- package/dist/{chunk-3JEAPZ6A.mjs → chunk-72YH2GXC.mjs} +3 -3
- package/dist/{chunk-3JEAPZ6A.mjs.map → chunk-72YH2GXC.mjs.map} +1 -1
- package/dist/{chunk-SZCIXA5X.mjs → chunk-CMPOHTUM.mjs} +44 -13
- package/dist/chunk-CMPOHTUM.mjs.map +1 -0
- package/dist/{chunk-DU6I4ZU2.mjs → chunk-YEKCBVNJ.mjs} +3 -3
- package/dist/{chunk-DU6I4ZU2.mjs.map → chunk-YEKCBVNJ.mjs.map} +1 -1
- package/dist/index.cjs +52 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.mjs +7 -6
- package/dist/index.mjs.map +1 -1
- package/dist/veo-builder.js +18 -18
- package/dist/veo-builder.js.map +1 -1
- package/dist/veo-guides.js +6 -6
- package/dist/veo-guides.js.map +1 -1
- package/dist/veo.js +2 -2
- package/dist/veo.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-SZCIXA5X.mjs.map +0 -1
package/dist/veo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contract/v1.ts","../src/core/api-url.ts","../src/utils/safe-env.ts","../src/core/builder-constants.ts","../src/core/preview-loader.ts","../src/core/builder-token.ts","../src/core/builder-loader.ts","../src/core/guides-loader.ts","../src/plugins/plugin.ts","../src/plugins/autocapture/constants.ts","../src/plugins/autocapture/selector-builder.ts","../src/plugins/autocapture/click-quality.ts","../src/plugins/autocapture/pii-guard.ts","../src/plugins/autocapture/element-serializer.ts","../src/plugins/autocapture/throttle.ts","../src/plugins/autocapture/dom-listener.ts","../src/plugins/autocapture/index.ts","../src/plugins/spa-router.ts","../src/plugins/theme-detect/index.ts","../src/utils/uuid.ts","../src/core/queue.ts","../src/core/session.ts","../src/core/storage.ts","../src/core/transport.ts","../src/core/client.ts","../src/core/setup.ts","../src/core/theme-loader.ts","../src/veo.ts"],"names":["SDK_VERSION","DEFAULT_API_URL","resolveApiUrl","config","fromConfig","fromGlobal","hasWindow","hasDocument","hasLocalStorage","testKey","hasNavigatorSendBeacon","BUILDER_TOKEN_PARAM","BUILDER_ORIGIN_PARAM","BUILDER_PANEL_PARAM","BUILDER_PANEL_PATH_PARAM","BUILDER_GUIDE_PARAM","PREVIEW_TOKEN_PARAM","PREVIEW_TOKEN_KEY","session","getPreviewToken","fromUrl","value","store","isPreviewMode","CTX_KEY","LS_PREFIX","PERSIST_TTL_MS","local","lsKey","guide","persist","ctx","stored","readFreshFromLocal","best","i","key","raw","parsed","_savedAt","urlParams","search","hash","resolveBuilderContext","params","fromLocal","resolveBuilderToken","isBuilderMode","maybeLoadBuilder","opts","url","deriveBuilderUrl","script","err","scripts","cached","loadGuides","loadInternal","resolve","win","deriveGuidesUrl","done","existing","definePlugin","plugin","DEFAULT_AUTOCAPTURE_CONFIG","MAX_ANCESTORS","ALWAYS_BLOCK_SELECTORS","SENSITIVE_ATTRIBUTES","PRIORITY_ATTRIBUTES","HASHED_CLASS_PATTERNS","isHashedClass","className","pattern","filterHumanClasses","element","c","STABLE_ATTRIBUTES","MAX_ATTR_VALUE_LENGTH","cssEscape","escapeAttrValue","stableAttributeSelector","tag","attr","buildElementSelector","veoTag","classes","classPart","attrSelector","buildSelectorPath","maxAncestors","parts","current","depth","NO_DEAD_TAGS","MAX_ERROR_MESSAGE","HISTORY_MS","DEFAULTS","describeError","text","ClickQualityTracker","emit","options","on","type","handler","capture","e","b","event","now","obs","netAtClick","navAtClick","focusAtClick","hrefAtClick","skipDead","observer","reacted","anchor","href","clickedAt","deadline","check","source","message","cutoff","list","kept","o","el","obsList","fast","slow","isRage","burst","clicks","kind","extra","counts","h","origPush","origReplace","self","args","orig","p","res","proto","origSend","isElementBlocked","extraBlockSelectors","allBlockers","selector","isSensitiveAttribute","attrName","lower","safeGetText","maxLength","mask","tagName","trimmed","extractPriorityAttributes","result","serializeElement","rect","serializeAncestors","maxDepth","ancestors","buildAutocapturePayload","eventType","ElementThrottle","windowMs","last","DomListener","client","d","payload","cleanup","eventName","useCapture","listener","target","meaningful","autocapturePlugin","spaRouterPlugin","fire","origPushState","origReplaceState","STORAGE_PREFIX","RESEND_AFTER_MS","SETTLE_MS","MAX_RUNS_PER_PAGE","readState","writeState","state","guessMode","doc","prefersDark","hints","isFresh","mode","shouldSendSnapshot","themeDetectPlugin","storageKey","timer","destroyed","runs","run","guess","detector","snapshot","mark","record","schedule","delayMs","idle","uuidv7","timeHex","random","hex","Queue","item","batch","error","maxRetries","base","ANONYMOUS_ID_KEY","END_USER_ID_KEY","SESSION_ID_KEY","SESSION_LAST_ACTIVE_KEY","SESSION_TIMEOUT_MS","Session","storage","id","lastActive","newId","ONE_YEAR_MS","LocalStorageAdapter","toRemove","readCookies","CookieAdapter","name","cookie","maxAgeSec","secure","eq","MemoryAdapter","createStorage","preferred","TransportError","statusCode","Transport","path","body","controller","timeoutMs","timeoutId","response","blob","ORGANIZATION_ID_KEY","IDENTIFY_SIG_KEY","stableStringify","k","Client","persistedUserId","persistedOrgId","visitor","organization","signature","previousAnonymousId","properties","pagePath","input","organizationId","pageUrl","pageTitle","pageReferrer","setupClient","onGuides","loadBuilder","loadThemeDetector","autocaptureConfig","pending","entry","method","fn","deriveThemeUrl","init","apiUrl","ensureGuides","previewToken","guides","inner","ready"],"mappings":"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","file":"veo.js","sourcesContent":["/**\n * Tipos del contrato HTTP entre el SDK y el backend.\n * Versión 1.\n *\n * IMPORTANTE: Si cambias algo aquí, debes actualizar también:\n * - veo-backend/src/modules/identity/dto/*.dto.ts\n * - veo-backend/src/modules/ingest/dto/*.dto.ts\n * - CONTRACT.md\n */\n\nexport const SDK_VERSION = '0.0.1';\nexport const MAX_BATCH_SIZE = 100;\nexport const DEFAULT_FLUSH_INTERVAL_MS = 5000;\nexport const DEFAULT_FLUSH_BATCH_SIZE = 20;\n\n/**\n * Backend de Veo, horneado en el bundle. El consumidor NO configura la URL.\n * El valor se inyecta en build-time desde `VEO_API_URL` (ver tsup.config.ts);\n * el literal de aquí es solo el fallback para tests / builds sin esa env.\n * NO es secreta: va al bundle del navegador, igual que la `pk_`.\n */\nexport const DEFAULT_API_URL =\n process.env.VEO_API_URL || 'https://veo-backend-production-8c78.up.railway.app';\n\n/**\n * Tipos de eventos que el SDK envía.\n * Debe coincidir con el CHECK constraint de veo_user_actions.action_type.\n */\nexport type ActionType = 'pageview' | 'track' | 'identify' | 'guide';\n\n/**\n * Payload de un evento individual enviado al endpoint POST /v1/events.\n */\nexport interface ActionPayload {\n actionId: string; // UUID v7 generado en cliente\n endUserId: string;\n organizationId?: string;\n sessionId: string;\n actionType: ActionType;\n actionName?: string;\n occurredAt: string; // ISO 8601\n pageUrl?: string;\n pagePath?: string;\n pageTitle?: string;\n pageReferrer?: string;\n actionProperties?: Record<string, unknown>;\n}\n\n/**\n * Request del endpoint POST /v1/events.\n */\nexport interface IngestEventsRequest {\n events: ActionPayload[]; // máx 100\n}\n\n/**\n * Response del endpoint POST /v1/events.\n */\nexport interface IngestEventsResponse {\n accepted: number;\n deduped: number;\n}\n\n/**\n * Request del endpoint POST /v1/identify.\n */\nexport interface IdentifyRequest {\n endUser: {\n id: string;\n anonymousId?: string;\n traits?: Record<string, unknown>;\n };\n organization?: {\n id: string;\n attributes?: Record<string, unknown>;\n };\n}\n\n/**\n * Response del endpoint POST /v1/identify.\n */\nexport interface IdentifyResponse {\n endUserId: string;\n organizationId: string | null;\n workspaceId: string;\n}\n\n/**\n * Response de error estándar del backend.\n */\nexport interface ErrorResponse {\n error: string;\n details?: unknown;\n statusCode: number;\n}\n","import { DEFAULT_API_URL } from '../contract/v1';\n\n/**\n * Resuelve la URL del backend de Veo. NO es parte de la API pública: el\n * consumidor solo pasa `apiKey` y la URL va quemada en `DEFAULT_API_URL`.\n *\n * Orden de resolución (para desarrollo local / self-host, sin recompilar):\n * 1. `config.apiUrl` si viene (override interno, no tipado en `VeoConfig`).\n * 2. `window.__VEO_API_URL__` si está seteado ANTES de `init()`.\n * 3. `DEFAULT_API_URL` (el backend gestionado).\n */\nexport function resolveApiUrl(config?: unknown): string {\n const fromConfig = (config as { apiUrl?: unknown } | undefined)?.apiUrl;\n if (typeof fromConfig === 'string' && fromConfig.trim()) return fromConfig;\n\n const fromGlobal = (globalThis as { __VEO_API_URL__?: unknown }).__VEO_API_URL__;\n if (typeof fromGlobal === 'string' && fromGlobal.trim()) return fromGlobal;\n\n return DEFAULT_API_URL;\n}\n","/**\n * Helpers para detectar el entorno de ejecución (browser vs SSR/Node) y la\n * disponibilidad de APIs del navegador. El SDK debe poder importarse en Node\n * sin romperse, por eso todo acceso a globals del browser pasa por aquí.\n */\n\n/** ¿Existe el objeto global `window`? */\nexport function hasWindow(): boolean {\n return typeof window !== 'undefined';\n}\n\n/** ¿Existe el objeto global `document`? */\nexport function hasDocument(): boolean {\n return typeof document !== 'undefined';\n}\n\n/** ¿`localStorage` está disponible y es escribible? (puede fallar en modo incógnito) */\nexport function hasLocalStorage(): boolean {\n try {\n if (typeof localStorage === 'undefined') return false;\n const testKey = '__veo_test__';\n localStorage.setItem(testKey, '1');\n localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n}\n\n/** ¿`navigator.sendBeacon` está disponible? */\nexport function hasNavigatorSendBeacon(): boolean {\n return typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function';\n}\n","/**\n * Nombres de los query params del puente builder. Constantes PURAS (sin DOM ni\n * `window`) para poder compartirlas entre el core (browser: `builder-token.ts`)\n * y el helper de servidor `veo-sdk/next` (`src/next.ts`), sin arrastrar código de\n * navegador al bundle de servidor.\n */\n\n/** Token de correlación del handshake. */\nexport const BUILDER_TOKEN_PARAM = 'veoBuilder';\n/** Origen del dashboard de Veo (para postMessage / frame-ancestors). */\nexport const BUILDER_ORIGIN_PARAM = 'veoBuilderOrigin';\n/** `1` → modo \"panel inyectado\": la app es top-level y el editor se inyecta encima. */\nexport const BUILDER_PANEL_PARAM = 'veoBuilderPanel';\n/** Path del panel del editor en el dashboard (default `/guides/design`). */\nexport const BUILDER_PANEL_PATH_PARAM = 'veoBuilderPanelPath';\n/** Id de la guía que se está editando (para cargar/guardar en el panel). */\nexport const BUILDER_GUIDE_PARAM = 'veoGuide';\n","/**\n * Detección del modo PREVIEW POR LINK (`?veoPreview=<token>`). El core solo\n * detecta el param — el canje del token y el render viven en el bundle de\n * guías (`plugins/guides/preview-mode.ts`), que el caller carga\n * (estático en `index.ts`, lazy en `veo.ts`).\n *\n * El nombre del query param es parte del contrato con el dashboard (el link\n * generado por «Previsualizar en mi app»).\n */\nimport { hasWindow } from '../utils/safe-env';\n\nexport const PREVIEW_TOKEN_PARAM = 'veoPreview';\n/**\n * El token se PERSISTE en sessionStorage: al navegar entre páginas de la app la\n * URL pierde `?veoPreview`, y sin esto el modo preview (y su chip de control) se\n * apagaba al saltar de página. sessionStorage sobrevive la navegación de la\n * pestaña y muere al cerrarla — justo el alcance de una sesión de preview.\n */\nconst PREVIEW_TOKEN_KEY = 'veo:preview_token';\n\nfunction session(): Storage | null {\n try {\n return window.sessionStorage;\n } catch {\n return null; // modo privado / sandbox: seguimos solo con la URL\n }\n}\n\n/**\n * Token del link de preview. Lo toma de la URL (`?veoPreview`) y lo persiste; si\n * la URL no lo trae (navegó a otra página), lo recupera de sessionStorage.\n * `null` si no hay ninguno. Se limpia con {@link clearPreviewToken}.\n */\nexport function getPreviewToken(): string | null {\n if (!hasWindow()) return null;\n let fromUrl: string | null = null;\n try {\n const value = new URLSearchParams(window.location.search).get(PREVIEW_TOKEN_PARAM);\n fromUrl = value ? value : null;\n } catch {\n fromUrl = null;\n }\n const store = session();\n if (fromUrl) {\n try {\n store?.setItem(PREVIEW_TOKEN_KEY, fromUrl);\n } catch {\n // no-op: sin storage seguimos con el token de la URL\n }\n return fromUrl;\n }\n try {\n return store?.getItem(PREVIEW_TOKEN_KEY) || null;\n } catch {\n return null;\n }\n}\n\n/** Sale del modo preview: borra el token persistido (lo llama el chip al cerrar). */\nexport function clearPreviewToken(): void {\n try {\n session()?.removeItem(PREVIEW_TOKEN_KEY);\n } catch {\n // no-op\n }\n}\n\n/**\n * `true` cuando la app corre en modo preview-por-link. Igual que en modo\n * builder, el runtime NO debe instalar el plugin de guías: las guías live\n * taparían/duplicarían la guía que se está previsualizando.\n */\nexport function isPreviewMode(): boolean {\n return getPreviewToken() !== null;\n}\n","/**\n * Resolución + persistencia del CONTEXTO de builder.\n *\n * El contexto viaja en la URL (`?veoBuilder=<token>&veoBuilderOrigin=<origen>…`),\n * pero los guards de auth de la app suelen **redirigir y tirar el query string**\n * (p.ej. `/dashboard/home` → `/` para loguearte). Si dependiéramos solo de la URL,\n * el modo builder moriría en ese redirect y nunca podrías diseñar sobre una página\n * detrás de login.\n *\n * Solución (igual que el \"designer mode\" de Pendo): apenas vemos el token en la\n * URL guardamos el contexto en `sessionStorage` y de ahí en más lo leemos como\n * fallback. Así el modo builder **sobrevive a redirects y a un login** dentro de la\n * misma pestaña (incluido el ida-y-vuelta de OAuth). Persiste hasta el teardown o\n * hasta que se cierra la pestaña.\n *\n * Vive en el core (bundle de producción) porque tanto el loader del builder como\n * el gate del runtime de guías necesitan saber si estamos en modo builder. Es\n * mínimo a propósito (ver budget en CLAUDE.md).\n */\nimport { hasWindow } from '../utils/safe-env';\nimport {\n BUILDER_GUIDE_PARAM,\n BUILDER_ORIGIN_PARAM,\n BUILDER_PANEL_PARAM,\n BUILDER_PANEL_PATH_PARAM,\n BUILDER_TOKEN_PARAM,\n} from './builder-constants';\nimport { isPreviewMode } from './preview-loader';\n\n// Re-export para no romper a quien los importa desde aquí (bridge-protocol, etc.).\nexport { BUILDER_ORIGIN_PARAM, BUILDER_TOKEN_PARAM } from './builder-constants';\n\n/** Contexto de la sesión de builder activa en la app. */\nexport interface BuilderClientContext {\n /** Token de correlación del handshake. */\n token: string;\n /** Origen del dashboard de Veo (para postMessage). */\n origin: string | null;\n /** `true` → modo panel inyectado (app top-level, editor encima). */\n panel: boolean;\n /** Id de la guía en edición (para el panel). */\n guide: string | null;\n /** Path del panel del editor en el dashboard (override; default `/guides/design`). */\n panelPath: string | null;\n}\n\nconst CTX_KEY = 'veo:builder_ctx';\n/**\n * Respaldo en localStorage, KEYED POR GUÍA. sessionStorage muere al cerrar la\n * pestaña; para que la sesión del editor \"perdure\" al abrir varias guías o\n * reabrir la misma, además persistimos por guía en localStorage con un TTL.\n * Keyed por guía → dos guías abiertas en pestañas distintas no se pisan.\n */\nconst LS_PREFIX = 'veo:builder_ctx:';\n/**\n * TTL del respaldo. Antes era 12 h y producía \"sesiones fantasma\": cerrabas la\n * pestaña del editor sin teardown y CUALQUIER visita a la app durante 12 h\n * restauraba un contexto viejo (token/plantilla stale) o re-abría el panel.\n * 30 min alcanza para su propósito real — sobrevivir el ida-y-vuelta del login\n * y recuperar un cierre accidental — sin arrastrar sesiones de ayer.\n */\nconst PERSIST_TTL_MS = 30 * 60 * 1000; // 30 min\n\ninterface StoredCtx extends BuilderClientContext {\n savedAt: number;\n}\n\nfunction session(): Storage | null {\n try {\n return window.sessionStorage;\n } catch {\n return null; // sessionStorage puede tirar (modo privado, sandbox)\n }\n}\n\nfunction local(): Storage | null {\n try {\n return window.localStorage;\n } catch {\n return null;\n }\n}\n\nfunction lsKey(guide: string | null): string {\n return LS_PREFIX + (guide || 'default');\n}\n\n/** Persiste el contexto en sessionStorage (pestaña) + localStorage por guía (TTL). */\nfunction persist(ctx: BuilderClientContext): void {\n try {\n session()?.setItem(CTX_KEY, JSON.stringify(ctx));\n } catch {\n // no-op: sin sessionStorage seguimos con el contexto de la URL\n }\n try {\n const stored: StoredCtx = { ...ctx, savedAt: Date.now() };\n local()?.setItem(lsKey(ctx.guide), JSON.stringify(stored));\n } catch {\n // no-op\n }\n}\n\n/** Contexto más reciente no vencido en localStorage (limpia los vencidos de paso). */\nfunction readFreshFromLocal(): BuilderClientContext | null {\n const store = local();\n if (!store) return null;\n let best: StoredCtx | null = null;\n try {\n for (let i = 0; i < store.length; i++) {\n const key = store.key(i);\n if (!key?.startsWith(LS_PREFIX)) continue;\n const raw = store.getItem(key);\n if (!raw) continue;\n let parsed: StoredCtx | null = null;\n try {\n parsed = JSON.parse(raw) as StoredCtx;\n } catch {\n continue;\n }\n if (typeof parsed?.savedAt !== 'number' || Date.now() - parsed.savedAt > PERSIST_TTL_MS) {\n try {\n store.removeItem(key);\n } catch {\n // no-op\n }\n continue;\n }\n if (!best || parsed.savedAt > best.savedAt) best = parsed;\n }\n } catch {\n return null;\n }\n if (!best) return null;\n const { savedAt: _savedAt, ...ctx } = best;\n return ctx;\n}\n\nfunction urlParams(): URLSearchParams | null {\n try {\n const search = new URLSearchParams(window.location.search);\n if (search.get(BUILDER_TOKEN_PARAM)) return search;\n // Fallback: FRAGMENTO (#veoBuilder=…). El dashboard duplica los params en el\n // hash porque, con sesión iniciada en la app, el guard de auth suele\n // redirigir la raíz y el redirect tira el query string — pero los\n // navegadores preservan el fragmento a través de los 3xx. Sin esto, el\n // editor solo abría con el usuario deslogueado.\n const hash = window.location.hash.replace(/^#/, '');\n if (hash.includes(`${BUILDER_TOKEN_PARAM}=`)) return new URLSearchParams(hash);\n return search;\n } catch {\n return null;\n }\n}\n\n/**\n * Contexto de builder activo: el de la URL (que además se persiste) o, si el\n * query string se perdió en un redirect, el guardado en sessionStorage. `null`\n * si no estamos en modo builder.\n */\nexport function resolveBuilderContext(): BuilderClientContext | null {\n if (!hasWindow()) return null;\n const params = urlParams();\n const fromUrl = params?.get(BUILDER_TOKEN_PARAM);\n if (fromUrl) {\n const ctx: BuilderClientContext = {\n token: fromUrl,\n origin: params?.get(BUILDER_ORIGIN_PARAM) ?? null,\n panel: params?.get(BUILDER_PANEL_PARAM) === '1',\n guide: params?.get(BUILDER_GUIDE_PARAM) ?? null,\n panelPath: params?.get(BUILDER_PANEL_PATH_PARAM) ?? null,\n };\n persist(ctx);\n return ctx;\n }\n // Preview-por-link (`?veoPreview`) es un modo EXCLUYENTE del builder: si la app\n // corre en preview NO revivimos una sesión de builder desde la persistencia.\n // Sin esto, abrir un link de preview dentro de los 30 min de haber editado\n // resucitaba el contexto de localStorage y RE-INYECTABA el editor ENCIMA del\n // preview — y ese remonte podía tirar el trabajo sin guardar. Un `?veoBuilder`\n // explícito en la URL sí gana (se resolvió arriba, antes de este chequeo).\n if (isPreviewMode()) return null;\n // Sin token en la URL: primero la pestaña (sessionStorage), y si murió (pestaña\n // nueva / restaurada) caemos al respaldo persistido más reciente y lo\n // re-hidratamos en la sesión para que el resto de la carga sea consistente.\n try {\n const raw = session()?.getItem(CTX_KEY);\n if (raw) return JSON.parse(raw) as BuilderClientContext;\n } catch {\n // sigue al fallback de localStorage\n }\n const fromLocal = readFreshFromLocal();\n if (fromLocal) {\n try {\n session()?.setItem(CTX_KEY, JSON.stringify(fromLocal));\n } catch {\n // no-op\n }\n }\n return fromLocal;\n}\n\n/** Token de builder activo (URL o persistido). */\nexport function resolveBuilderToken(): string | null {\n return resolveBuilderContext()?.token ?? null;\n}\n\n/** Origen del dashboard (URL o persistido). */\nexport function resolveBuilderOrigin(): string | null {\n return resolveBuilderContext()?.origin ?? null;\n}\n\n/** `true` si hay un contexto de builder activo (URL o persistido). */\nexport function isBuilderMode(): boolean {\n return resolveBuilderContext() !== null;\n}\n\n/**\n * Borra el modo builder persistido (al hacer teardown / salir del editor).\n * Limpia la pestaña (sessionStorage) y el respaldo de ESTA guía (localStorage);\n * los respaldos de otras guías siguen (no se pisan al cerrar una).\n */\nexport function clearBuilderToken(): void {\n if (!hasWindow()) return;\n let guide: string | null = null;\n try {\n const raw = session()?.getItem(CTX_KEY);\n if (raw) guide = (JSON.parse(raw) as BuilderClientContext).guide ?? null;\n } catch {\n // no-op\n }\n try {\n session()?.removeItem(CTX_KEY);\n } catch {\n // no-op\n }\n try {\n local()?.removeItem(lsKey(guide));\n } catch {\n // no-op\n }\n}\n","/**\n * Carga perezosa del bundle del builder. El SDK de producción (`veo.js`) es\n * lo único que el cliente integra; cuando el dashboard abre la app con\n * `?veoBuilder=<token>`, este loader inyecta `veo-builder.js` (que se\n * auto-conecta). Así el modo no-code \"simplemente funciona\" sin que el\n * cliente tenga que instalar nada extra.\n *\n * No importa nada del plugin builder para no arrastrar su código al bundle\n * de producción (ver budget en CLAUDE.md). El nombre del query param debe\n * coincidir con `BUILDER_TOKEN_PARAM` de `plugins/builder/bridge-protocol`.\n */\nimport { hasDocument, hasWindow } from '../utils/safe-env';\nimport { resolveBuilderToken } from './builder-token';\n\n/**\n * `true` cuando la app corre en modo builder (URL con `?veoBuilder=<token>`, o\n * el token persistido en sessionStorage tras un redirect de auth). En ese modo\n * el editor pinta las guías vía PREVIEW; el runtime NO debe resolver/renderizar\n * las guías `live` o se duplicarían (la live del runtime + la preview del editor).\n */\nexport { isBuilderMode } from './builder-token';\n\nexport function maybeLoadBuilder(opts: {\n builderUrl?: string;\n debug?: boolean;\n apiKey?: string;\n apiUrl?: string;\n /**\n * Fallback para integraciones por bundler (sin `<script>` de dónde derivar la\n * URL): carga el builder con un `import()` dinámico. Lo pasa SOLO el entry\n * ESM/CJS (`index.ts`), así el bundler lo code-splitea (cero costo en prod, se\n * descarga solo en modo builder). El IIFE NO lo pasa (usa el `<script>`).\n */\n loadBuilder?: () => Promise<unknown>;\n}): void {\n if (!hasWindow() || !hasDocument()) return;\n\n // Lee el token de la URL o de sessionStorage (sobrevive al redirect que tira\n // el query string) y persiste el de la URL apenas lo ve. Sin token → no-op.\n if (resolveBuilderToken() === null) return;\n\n // Dejamos apiKey/apiUrl en un global para que el modo builder VERIFIQUE el\n // token contra el backend (`/v1/builder/verify`) antes de activarse. Solo se\n // setea cuando el builder se carga desde `init()` (integración real); en\n // demos que cargan veo-builder.js a mano no existe → verificación best-effort.\n if (opts.apiKey && opts.apiUrl) {\n (window as unknown as { __veoBuilder?: unknown }).__veoBuilder = {\n apiKey: opts.apiKey,\n apiUrl: opts.apiUrl,\n };\n }\n\n // Ya cargado (el IIFE expone window.veoBuilder).\n if ((window as unknown as { veoBuilder?: unknown }).veoBuilder) return;\n\n const url = opts.builderUrl ?? deriveBuilderUrl();\n if (url) {\n if (document.querySelector(`script[src=\"${url}\"]`)) return;\n const script = document.createElement('script');\n script.src = url;\n script.async = true;\n if (opts.debug) {\n script.addEventListener('error', () => console.error('[veo] no pude cargar', url));\n }\n document.head.appendChild(script);\n return;\n }\n\n // Integración por bundler: no hay `<script>` que derivar. Cargamos el builder\n // con el `import()` dinámico que pasó el entry ESM/CJS. El consumidor NO tiene\n // que copiar `veo-builder.js` ni setear `builderUrl`: \"simplemente funciona\".\n if (opts.loadBuilder) {\n void opts.loadBuilder().catch((err) => {\n if (opts.debug) console.error('[veo] no pude cargar el builder (import dinámico)', err);\n });\n return;\n }\n\n if (opts.debug) {\n console.warn('[veo] builder mode pedido pero no pude resolver la URL de veo-builder.js');\n }\n}\n\n/** Deriva `veo-builder.js` del `<script>` que cargó `veo.js`. */\nfunction deriveBuilderUrl(): string | null {\n const scripts = document.querySelectorAll<HTMLScriptElement>('script[src]');\n for (const script of Array.from(scripts)) {\n if (/\\bveo(\\.min)?\\.js(\\?.*)?$/.test(script.src)) {\n return script.src.replace(/\\bveo(\\.min)?\\.js/, 'veo-builder$1.js');\n }\n }\n return null;\n}\n","/**\n * Carga PEREZOSA del bundle de guías (`veo-guides.js`). El `veo.js` de\n * producción no incluye los renderers ni Floating UI; este loader inyecta el\n * bundle de guías y resuelve con su API (`window.veoGuides`) la primera vez que\n * hace falta (`guides:true` o `veo.preview()`).\n *\n * No importa NADA del plugin guides como valor (solo tipos, que se borran) para\n * no arrastrar su código al bundle principal — igual que `builder-loader`.\n */\nimport type {\n GuidesPluginConfig,\n PreviewGuideInput,\n PreviewHandle,\n PreviewModeHandle,\n PreviewModeOptions,\n} from '../plugins/guides';\nimport type { VeoPlugin } from '../types';\nimport { hasDocument, hasWindow } from '../utils/safe-env';\n\nexport interface VeoGuidesApi {\n guidesPlugin: (config: GuidesPluginConfig) => VeoPlugin;\n previewGuide: (input: PreviewGuideInput) => PreviewHandle;\n closeGuidePreview: () => void;\n runPreviewMode: (opts: PreviewModeOptions) => Promise<PreviewModeHandle | null>;\n}\n\ninterface WindowWithGuides {\n veoGuides?: VeoGuidesApi;\n}\n\nlet cached: Promise<VeoGuidesApi | null> | null = null;\n\n/** Carga (una vez) el bundle de guías y resuelve con su API, o `null` si falla. */\nexport function loadGuides(opts: {\n guidesUrl?: string;\n debug?: boolean;\n}): Promise<VeoGuidesApi | null> {\n cached ??= loadInternal(opts);\n return cached;\n}\n\nfunction loadInternal(opts: { guidesUrl?: string; debug?: boolean }): Promise<VeoGuidesApi | null> {\n return new Promise((resolve) => {\n if (!hasWindow() || !hasDocument()) {\n resolve(null);\n return;\n }\n const win = window as unknown as WindowWithGuides;\n if (win.veoGuides) {\n resolve(win.veoGuides);\n return;\n }\n\n const url = opts.guidesUrl ?? deriveGuidesUrl();\n if (!url) {\n if (opts.debug) console.warn('[veo] no pude resolver la URL de veo-guides.js');\n resolve(null);\n return;\n }\n\n const done = (): void => resolve(win.veoGuides ?? null);\n const existing = document.querySelector<HTMLScriptElement>(`script[src=\"${url}\"]`);\n if (existing) {\n existing.addEventListener('load', done);\n existing.addEventListener('error', () => resolve(null));\n return;\n }\n\n const script = document.createElement('script');\n script.src = url;\n script.async = true;\n script.addEventListener('load', done);\n script.addEventListener('error', () => {\n if (opts.debug) console.error('[veo] no pude cargar', url);\n resolve(null);\n });\n document.head.appendChild(script);\n });\n}\n\n/** Deriva `veo-guides.js` del `<script>` que cargó `veo.js`. */\nfunction deriveGuidesUrl(): string | null {\n const scripts = document.querySelectorAll<HTMLScriptElement>('script[src]');\n for (const script of Array.from(scripts)) {\n if (/\\bveo(\\.min)?\\.js(\\?.*)?$/.test(script.src)) {\n return script.src.replace(/\\bveo(\\.min)?\\.js/, 'veo-guides$1.js');\n }\n }\n return null;\n}\n","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","/** Configuración default de autocaptura. */\nexport const DEFAULT_AUTOCAPTURE_CONFIG = {\n enabled: true,\n captureClicks: true,\n captureSubmits: true,\n captureChanges: true,\n maskAllInputs: true,\n maskAllText: false,\n throttleMs: 100,\n maxTextLength: 200,\n captureElementMetadata: true,\n captureAncestors: 5,\n captureClickQuality: true,\n} as const;\n\n/** Máximo de niveles de ancestros que se permiten capturar. */\nexport const MAX_ANCESTORS = 10;\n\n/** Selectores que SIEMPRE se ignoran (incluso si el cliente no configura blockSelectors). */\nexport const ALWAYS_BLOCK_SELECTORS = [\n '[data-veo-ignore]',\n '.veo-ignore',\n // Inputs sensibles\n 'input[type=\"password\"]',\n 'input[type=\"email\"]',\n 'input[type=\"tel\"]',\n 'input[type=\"hidden\"]',\n // Datos de tarjeta\n '[autocomplete=\"cc-number\"]',\n '[autocomplete=\"cc-csc\"]',\n '[autocomplete=\"cc-exp\"]',\n '[autocomplete=\"cc-name\"]',\n // Otros campos sensibles típicos\n '[name*=\"password\" i]',\n '[name*=\"ssn\" i]',\n '[name*=\"credit\" i]',\n '[name*=\"card\" i]',\n '[id*=\"password\" i]',\n '[id*=\"ssn\" i]',\n];\n\n/** Atributos sensibles que NUNCA se capturan. */\nexport const SENSITIVE_ATTRIBUTES = ['value', 'data-credit-card', 'data-ssn', 'data-password'];\n\n/** Atributos útiles que SIEMPRE se intentan capturar si existen. */\nexport const PRIORITY_ATTRIBUTES = [\n 'id',\n 'name',\n 'type',\n 'role',\n 'href',\n 'data-action',\n 'data-veo-tag',\n 'data-testid',\n 'aria-label',\n 'aria-labelledby',\n];\n\n/** Regex para detectar clases generadas dinámicamente. Se descartan del selector. */\nexport const HASHED_CLASS_PATTERNS = [\n /^css-[a-z0-9]{4,}$/i, // emotion, styled-components nuevas\n /^_[a-z0-9]+_[a-z0-9]{4,}_\\d+$/, // CSS Modules con hash\n /^[a-z]{2,4}-[a-z0-9]{6,}$/i, // Tailwind JIT (a veces)\n /^[a-f0-9]{6,}$/i, // hashes hex puros\n /^sc-[a-z0-9]+$/i, // styled-components legacy\n];\n\n/** Eventos sintéticos/internos que ignoramos. */\nexport const IGNORED_EVENT_PROPERTIES = ['$autocapture', 'pageview'];\n","import { HASHED_CLASS_PATTERNS } from './constants';\n\n/** Determina si una clase parece generada dinámicamente (hash de CSS-in-JS, etc.). */\nexport function isHashedClass(className: string): boolean {\n return HASHED_CLASS_PATTERNS.some((pattern) => pattern.test(className));\n}\n\n/** Filtra las clases de un elemento para quedarse solo con las \"humanas\" (estables). */\nexport function filterHumanClasses(element: Element): string[] {\n return Array.from(element.classList).filter((c) => !isHashedClass(c) && c.length < 64);\n}\n\n/**\n * Atributos estables y semánticos que identifican un elemento mejor que sus\n * clases utilitarias (que cambian con el styling). Orden = prioridad. Producen\n * selectores legibles tipo `button[aria-label=\"Abrir menú\"]` que el usuario\n * puede escribir/reconocer en el editor de segmentos.\n */\nconst STABLE_ATTRIBUTES = [\n 'data-testid',\n 'data-test',\n 'data-cy',\n 'name',\n 'aria-label',\n 'placeholder',\n 'alt',\n 'title',\n // `href` identifica muy bien a los links (`<a>`), un target frecuente de\n // autocapture; va después de los atributos semánticos pero antes de los\n // genéricos. Valores largos (URLs absolutas con query) se descartan por\n // MAX_ATTR_VALUE_LENGTH.\n 'href',\n 'role',\n 'type',\n] as const;\n\n/** Valores de atributo más largos que esto se descartan (no son buenos selectores). */\nconst MAX_ATTR_VALUE_LENGTH = 100;\n\n/** Escape básico de caracteres especiales en CSS (usa CSS.escape si está disponible). */\nfunction cssEscape(value: string): string {\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(value);\n }\n return value.replace(/[!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&');\n}\n\n/**\n * Escape para un valor que va DENTRO de comillas en `[attr=\"...\"]`. A diferencia\n * de `cssEscape`, no escapa espacios ni acentos (las comillas ya los cubren):\n * solo `\\` y `\"`. Así el valor queda igual al texto real y el match por substring\n * del backend funciona con lo que el usuario escribe.\n */\nfunction escapeAttrValue(value: string): string {\n return value.replace(/[\\\\\"]/g, '\\\\$&');\n}\n\n/** Devuelve un selector por atributo estable si el elemento tiene alguno. */\nfunction stableAttributeSelector(element: Element, tag: string): string | null {\n for (const attr of STABLE_ATTRIBUTES) {\n const value = element.getAttribute(attr);\n if (value && value.length > 0 && value.length <= MAX_ATTR_VALUE_LENGTH) {\n return `${tag}[${attr}=\"${escapeAttrValue(value)}\"]`;\n }\n }\n return null;\n}\n\n/** Construye un selector simple y estable para UN elemento. */\nfunction buildElementSelector(element: Element): string {\n const tag = element.tagName.toLowerCase();\n\n // 1. `data-veo-tag`: el nombre semántico que da el cliente. Máxima prioridad.\n const veoTag = element.getAttribute('data-veo-tag');\n if (veoTag) {\n return `${tag}[data-veo-tag=\"${escapeAttrValue(veoTag)}\"]`;\n }\n\n // 2. `id`: único y estable. Lo combinamos con clases humanas (como antes).\n if (element.id) {\n const classes = filterHumanClasses(element);\n const classPart = classes.length > 0 ? `.${classes.map(cssEscape).join('.')}` : '';\n return `${tag}#${cssEscape(element.id)}${classPart}`;\n }\n\n // 3. Atributo estable (aria-label, name, type, role…): más robusto que clases.\n const attrSelector = stableAttributeSelector(element, tag);\n if (attrSelector) return attrSelector;\n\n // 4. Fallback: clases humanas.\n const classes = filterHumanClasses(element);\n const classPart = classes.length > 0 ? `.${classes.map(cssEscape).join('.')}` : '';\n return `${tag}${classPart}`;\n}\n\n/** Construye un selector CSS legible y razonablemente estable para el elemento. */\nexport function buildSelectorPath(element: Element, maxAncestors = 5): string {\n const parts: string[] = [];\n let current: Element | null = element;\n let depth = 0;\n\n while (current && current !== document.documentElement && depth <= maxAncestors) {\n parts.unshift(buildElementSelector(current));\n current = current.parentElement;\n depth++;\n }\n\n return parts.join(' > ');\n}\n","import { hasWindow } from '../../utils/safe-env';\nimport { buildSelectorPath } from './selector-builder';\n\n/**\n * Calidad de los clics (Features → detalle: «Clics de error», «Rage clicks»,\n * «Dead clicks»). Nada se decide mirando el elemento: se observa lo que pasa en\n * la página DESPUÉS del clic durante una ventana corta.\n *\n * - **Dead click:** en `reactionWindowMs` no hubo mutación del DOM, ni cambio\n * de URL, ni petición de red, ni cambio de foco. Cubre botones sin handler,\n * enlaces sin href y handlers que no hacen nada. Una navegación completa\n * (pagehide) cuenta como reacción.\n * - **Rage click:** ≥`rageClicks` clics en `rageWindowMs` (o ≥`rageClicksSlow`\n * en `rageWindowSlowMs`) sobre el mismo elemento. UN evento por ráfaga con\n * `$click_count` y `$reacted_clicks` (cuántos de esos clics sí produjeron\n * reacción: sirve para filtrar contadores/carruseles en el análisis, pero la\n * ráfaga se registra siempre — la frustración es la frecuencia).\n * - **Error click:** en `errorWindowMs` hubo un error JS global, una promesa\n * rechazada sin manejar, un `console.error` o una respuesta de red ≥500.\n *\n * Los tres viajan como `track('$dead_click' | '$rage_click' | '$click_error',\n * payload de autocapture + extras)` por la misma cola, con el mismo\n * `$selector_path`/`$page_path` que los clics: el backend los cuenta con el\n * mismo matching de selectores. Tope `maxPerElement` por elemento y tipo por\n * sesión. Los observadores viven solo durante la ventana.\n */\n\nexport type ClickQualityKind = '$dead_click' | '$rage_click' | '$click_error';\n\nexport interface ClickQualityOptions {\n reactionWindowMs?: number;\n errorWindowMs?: number;\n rageClicks?: number;\n rageWindowMs?: number;\n rageClicksSlow?: number;\n rageWindowSlowMs?: number;\n maxPerElement?: number;\n}\n\nexport type ClickQualityEmit = (\n kind: ClickQualityKind,\n element: Element,\n extra: Record<string, unknown>,\n) => void;\n\ninterface ErrorSignal {\n at: number;\n source: 'error' | 'unhandledrejection' | 'console' | 'fetch' | 'xhr';\n message: string;\n}\n\n/** Observación de un clic: reacción (dead) y errores (error). */\ninterface Observation {\n at: number;\n reacted: boolean;\n}\n\ninterface Burst {\n startedAt: number;\n count: number;\n timer: number;\n}\n\n/** Elementos donde un clic sin reacción visible es normal (escribir, elegir). */\nconst NO_DEAD_TAGS = new Set(['input', 'textarea', 'select', 'option', 'label']);\nconst MAX_ERROR_MESSAGE = 200;\n/** Historial de clics por elemento que se conserva (para la ventana lenta de rage). */\nconst HISTORY_MS = 3000;\n\nconst DEFAULTS: Required<ClickQualityOptions> = {\n reactionWindowMs: 1000,\n errorWindowMs: 2000,\n rageClicks: 3,\n rageWindowMs: 1000,\n rageClicksSlow: 5,\n rageWindowSlowMs: 3000,\n maxPerElement: 50,\n};\n\nfunction describeError(value: unknown): string {\n let text: string;\n if (value instanceof Error) text = `${value.name}: ${value.message}`;\n else if (typeof value === 'string') text = value;\n else {\n try {\n text = JSON.stringify(value) ?? String(value);\n } catch {\n text = String(value);\n }\n }\n return text.slice(0, MAX_ERROR_MESSAGE);\n}\n\nexport class ClickQualityTracker {\n private readonly opts: Required<ClickQualityOptions>;\n private installed = false;\n private cleanups: Array<() => void> = [];\n\n // Sensores globales (contadores: cada observación compara su foto inicial).\n private netCount = 0;\n private navCount = 0;\n private focusCount = 0;\n private unloading = false;\n private errors: ErrorSignal[] = [];\n\n private readonly history = new Map<Element, Observation[]>();\n private readonly bursts = new Map<Element, Burst>();\n private readonly emitted = new Map<string, Record<ClickQualityKind, number>>();\n\n constructor(\n private readonly emit: ClickQualityEmit,\n options: ClickQualityOptions = {},\n ) {\n this.opts = { ...DEFAULTS, ...options };\n }\n\n install(): void {\n if (this.installed || !hasWindow()) return;\n this.installed = true;\n\n const on = <K extends keyof WindowEventMap>(\n type: K,\n handler: (e: WindowEventMap[K]) => void,\n capture = true,\n ): void => {\n window.addEventListener(type, handler, capture);\n this.cleanups.push(() => window.removeEventListener(type, handler, capture));\n };\n\n on('error', (e) => {\n const err = e as ErrorEvent;\n this.pushError('error', err.error ?? err.message ?? 'error');\n });\n on('unhandledrejection', (e) => {\n this.pushError('unhandledrejection', (e as PromiseRejectionEvent).reason ?? 'rejection');\n });\n on('popstate', () => this.navCount++);\n on('hashchange', () => this.navCount++);\n on('focusin', () => this.focusCount++);\n on('pagehide', () => {\n this.unloading = true;\n });\n on('beforeunload', () => {\n this.unloading = true;\n });\n\n this.patchHistory();\n this.patchConsole();\n this.patchFetch();\n this.patchXhr();\n }\n\n destroy(): void {\n for (const c of this.cleanups) c();\n this.cleanups = [];\n for (const b of this.bursts.values()) window.clearTimeout(b.timer);\n this.bursts.clear();\n this.history.clear();\n this.installed = false;\n }\n\n /** Llamar por cada clic real sobre un elemento interactivo, ANTES del throttle. */\n onClick(element: Element, event?: Partial<MouseEvent>): void {\n if (!this.installed) return;\n const now = Date.now();\n const obs: Observation = { at: now, reacted: false };\n this.remember(element, obs);\n this.observeReaction(element, obs, event);\n this.observeErrors(element, now);\n this.trackRage(element, now);\n }\n\n // ---------------------------------------------------------------- dead ----\n\n private observeReaction(element: Element, obs: Observation, event?: Partial<MouseEvent>): void {\n const netAtClick = this.netCount;\n const navAtClick = this.navCount;\n const focusAtClick = this.focusCount;\n const hrefAtClick = window.location.href;\n const skipDead = this.isDeadExempt(element, event);\n\n let observer: MutationObserver | null = null;\n if (typeof MutationObserver !== 'undefined') {\n observer = new MutationObserver(() => {\n obs.reacted = true;\n observer?.disconnect();\n observer = null;\n });\n observer.observe(document.documentElement, {\n childList: true,\n attributes: true,\n characterData: true,\n subtree: true,\n });\n }\n window.setTimeout(() => {\n observer?.disconnect();\n const reacted =\n obs.reacted ||\n this.unloading ||\n this.netCount !== netAtClick ||\n this.navCount !== navAtClick ||\n this.focusCount !== focusAtClick ||\n window.location.href !== hrefAtClick;\n obs.reacted = reacted;\n if (!reacted && !skipDead) this.report('$dead_click', element, {});\n }, this.opts.reactionWindowMs);\n }\n\n private isDeadExempt(element: Element, event?: Partial<MouseEvent>): boolean {\n if (event && (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey)) return true;\n if (event && typeof event.button === 'number' && event.button !== 0) return true;\n const tag = element.tagName.toLowerCase();\n if (NO_DEAD_TAGS.has(tag)) return true;\n if (element.closest('[contenteditable=\"\"],[contenteditable=\"true\"]')) return true;\n const anchor = element.closest('a');\n if (anchor) {\n if (anchor.target === '_blank' || anchor.hasAttribute('download')) return true;\n const href = anchor.getAttribute('href') ?? '';\n if (/^(mailto|tel|sms):/i.test(href)) return true;\n }\n return false;\n }\n\n // --------------------------------------------------------------- error ----\n\n private observeErrors(element: Element, clickedAt: number): void {\n const deadline = clickedAt + this.opts.errorWindowMs;\n // Poll liviano: los errores llegan por listeners globales; acá solo se\n // asocia el primero posterior al clic dentro de la ventana.\n const check = (): void => {\n const err = this.errors.find((e) => e.at >= clickedAt && e.at <= deadline);\n if (err) {\n this.report('$click_error', element, {\n $error_source: err.source,\n $error_message: err.message,\n });\n return;\n }\n if (Date.now() < deadline) window.setTimeout(check, 250);\n };\n window.setTimeout(check, 250);\n }\n\n private pushError(source: ErrorSignal['source'], value: unknown): void {\n const message = describeError(value);\n if (message.startsWith('[veo]')) return; // logs propios del SDK\n this.errors.push({ at: Date.now(), source, message });\n // Mantener solo lo reciente: los observadores miran hacia atrás como mucho errorWindowMs.\n const cutoff = Date.now() - this.opts.errorWindowMs - 1000;\n while (this.errors.length > 0 && (this.errors[0] as ErrorSignal).at < cutoff) {\n this.errors.shift();\n }\n if (this.errors.length > 50) this.errors.splice(0, this.errors.length - 50);\n }\n\n // ---------------------------------------------------------------- rage ----\n\n private remember(element: Element, obs: Observation): void {\n const list = this.history.get(element) ?? [];\n const cutoff = obs.at - HISTORY_MS;\n const kept = list.filter((o) => o.at >= cutoff);\n kept.push(obs);\n this.history.set(element, kept);\n // No acumular elementos que ya no se clickean.\n if (this.history.size > 100) {\n for (const [el, obsList] of this.history) {\n if (obsList.every((o) => o.at < cutoff)) this.history.delete(el);\n }\n }\n }\n\n private trackRage(element: Element, now: number): void {\n const list = this.history.get(element) ?? [];\n const fast = list.filter((o) => o.at >= now - this.opts.rageWindowMs).length;\n const slow = list.filter((o) => o.at >= now - this.opts.rageWindowSlowMs).length;\n const existing = this.bursts.get(element);\n const isRage = fast >= this.opts.rageClicks || slow >= this.opts.rageClicksSlow;\n if (!existing && !isRage) return;\n\n const burst: Burst = existing ?? {\n startedAt: (list.find((o) => o.at >= now - this.opts.rageWindowSlowMs) ?? { at: now }).at,\n count: 0,\n timer: 0,\n };\n burst.count = list.filter((o) => o.at >= burst.startedAt).length;\n window.clearTimeout(burst.timer);\n // La ráfaga termina cuando pasa la ventana de reacción del último clic sin\n // clics nuevos: ahí ya se sabe si los clics reaccionaron.\n burst.timer = window.setTimeout(() => {\n this.bursts.delete(element);\n const clicks = (this.history.get(element) ?? []).filter((o) => o.at >= burst.startedAt);\n this.report('$rage_click', element, {\n $click_count: Math.max(clicks.length, burst.count),\n $reacted_clicks: clicks.filter((o) => o.reacted).length,\n });\n }, this.opts.reactionWindowMs + 50);\n this.bursts.set(element, burst);\n }\n\n // ---------------------------------------------------------------- emit ----\n\n private report(kind: ClickQualityKind, element: Element, extra: Record<string, unknown>): void {\n const key = buildSelectorPath(element, 5);\n const counts = this.emitted.get(key) ?? { $dead_click: 0, $rage_click: 0, $click_error: 0 };\n if (counts[kind] >= this.opts.maxPerElement) return;\n counts[kind]++;\n this.emitted.set(key, counts);\n try {\n this.emit(kind, element, extra);\n } catch {\n // nunca romper la app del cliente\n }\n }\n\n // ------------------------------------------------------------- patches ----\n\n private patchHistory(): void {\n const h = window.history;\n if (!h) return;\n const origPush = h.pushState;\n const origReplace = h.replaceState;\n const self = this;\n h.pushState = function (this: History, ...args: Parameters<History['pushState']>) {\n self.navCount++;\n return origPush.apply(this, args);\n };\n h.replaceState = function (this: History, ...args: Parameters<History['replaceState']>) {\n self.navCount++;\n return origReplace.apply(this, args);\n };\n this.cleanups.push(() => {\n h.pushState = origPush;\n h.replaceState = origReplace;\n });\n }\n\n private patchConsole(): void {\n const orig = console.error;\n const self = this;\n console.error = function (this: Console, ...args: unknown[]) {\n try {\n self.pushError('console', args.map(describeError).join(' '));\n } catch {\n // no-op\n }\n return orig.apply(this, args);\n };\n this.cleanups.push(() => {\n console.error = orig;\n });\n }\n\n /**\n * `fetch`: cuenta la petición (reacción) y registra respuestas ≥500 o\n * rechazos como error. Se observa con `.then(ok, err)` sobre la promesa\n * original: eso marca el rechazo como manejado para el navegador, así que\n * un fetch fallido sin catch de la app no dispara `unhandledrejection` —\n * lo registramos nosotros como error de red.\n */\n private patchFetch(): void {\n if (typeof window.fetch !== 'function') return;\n const orig = window.fetch;\n const self = this;\n window.fetch = function (this: unknown, ...args: Parameters<typeof fetch>) {\n self.netCount++;\n const p = orig.apply(this, args);\n if (p && typeof p.then === 'function') {\n p.then(\n (res) => {\n if (res && res.status >= 500) self.pushError('fetch', `${res.status} ${res.url}`);\n },\n (err) => self.pushError('fetch', err),\n );\n }\n return p;\n };\n this.cleanups.push(() => {\n window.fetch = orig;\n });\n }\n\n private patchXhr(): void {\n const proto = typeof XMLHttpRequest !== 'undefined' ? XMLHttpRequest.prototype : null;\n if (!proto) return;\n const origSend = proto.send;\n const self = this;\n proto.send = function (this: XMLHttpRequest, ...args: Parameters<XMLHttpRequest['send']>) {\n self.netCount++;\n try {\n this.addEventListener('loadend', () => {\n if (this.status >= 500) self.pushError('xhr', `${this.status} ${this.responseURL}`);\n });\n } catch {\n // no-op\n }\n return origSend.apply(this, args);\n };\n this.cleanups.push(() => {\n proto.send = origSend;\n });\n }\n}\n","import { ALWAYS_BLOCK_SELECTORS, SENSITIVE_ATTRIBUTES } from './constants';\n\n/**\n * Verifica si un elemento o ALGUNO de sus ancestros está en la blacklist.\n * Recorre hacia arriba para que bloquear un contenedor bloquee su subárbol.\n */\nexport function isElementBlocked(element: Element, extraBlockSelectors: string[] = []): boolean {\n const allBlockers = [...ALWAYS_BLOCK_SELECTORS, ...extraBlockSelectors];\n let current: Element | null = element;\n\n while (current && current !== document.documentElement) {\n for (const selector of allBlockers) {\n try {\n if (current.matches(selector)) return true;\n } catch {\n // Selector inválido o no soportado por el motor: ignorar y seguir.\n }\n }\n current = current.parentElement;\n }\n\n return false;\n}\n\n/** Verifica si un atributo es sensible y debe omitirse. */\nexport function isSensitiveAttribute(attrName: string): boolean {\n const lower = attrName.toLowerCase();\n return SENSITIVE_ATTRIBUTES.includes(lower) || /password|secret|token|ssn|credit/i.test(attrName);\n}\n\n/** Obtiene el texto visible de un elemento, respetando privacidad. */\nexport function safeGetText(element: Element, maxLength: number, mask: boolean): string {\n if (mask) return '';\n\n // Nunca capturar texto de campos de entrada (puede contener lo que el usuario escribe).\n const tagName = element.tagName.toLowerCase();\n if (tagName === 'input' || tagName === 'textarea') return '';\n\n // `innerText` no existe en jsdom; el fallback a `textContent` lo cubre.\n const raw =\n (element instanceof HTMLElement ? element.innerText : '') || element.textContent || '';\n const trimmed = raw.trim().replace(/\\s+/g, ' ');\n\n return trimmed.length > maxLength ? `${trimmed.slice(0, maxLength)}…` : trimmed;\n}\n","import { PRIORITY_ATTRIBUTES } from './constants';\nimport { isSensitiveAttribute, safeGetText } from './pii-guard';\nimport { buildSelectorPath, filterHumanClasses } from './selector-builder';\n\nexport interface SerializedElement {\n tag: string;\n id: string | null;\n classes: string[];\n text: string;\n attributes: Record<string, string>;\n position: { x: number; y: number; w: number; h: number };\n}\n\nexport interface SerializedAncestor {\n tag: string;\n id: string | null;\n classes: string[];\n veoTag: string | null;\n}\n\nexport interface AutocapturePayload {\n $event_type: 'click' | 'submit' | 'change';\n $element: SerializedElement;\n $ancestors: SerializedAncestor[];\n $selector_path: string;\n $page_url: string;\n $page_path: string;\n}\n\ninterface SerializeConfig {\n maxTextLength: number;\n maskAllText: boolean;\n captureElementMetadata: boolean;\n}\n\n/** Extrae los atributos relevantes del elemento, filtrando los sensibles. */\nfunction extractPriorityAttributes(element: Element): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const attrName of PRIORITY_ATTRIBUTES) {\n const value = element.getAttribute(attrName);\n if (value !== null && !isSensitiveAttribute(attrName) && value.length < 256) {\n result[attrName] = value;\n }\n }\n\n return result;\n}\n\n/** Serializa un elemento DOM a un objeto plano para enviar al backend. */\nexport function serializeElement(element: Element, config: SerializeConfig): SerializedElement {\n const rect = element.getBoundingClientRect();\n\n return {\n tag: element.tagName.toLowerCase(),\n id: element.id || null,\n classes: filterHumanClasses(element),\n text: safeGetText(element, config.maxTextLength, config.maskAllText),\n attributes: config.captureElementMetadata ? extractPriorityAttributes(element) : {},\n position: {\n x: Math.round(rect.left + window.scrollX),\n y: Math.round(rect.top + window.scrollY),\n w: Math.round(rect.width),\n h: Math.round(rect.height),\n },\n };\n}\n\n/** Captura los ancestros del elemento (para tagging contextual en el dashboard). */\nexport function serializeAncestors(element: Element, maxDepth: number): SerializedAncestor[] {\n const ancestors: SerializedAncestor[] = [];\n let current: Element | null = element.parentElement;\n let depth = 0;\n\n while (current && current !== document.documentElement && depth < maxDepth) {\n ancestors.push({\n tag: current.tagName.toLowerCase(),\n id: current.id || null,\n classes: filterHumanClasses(current),\n veoTag: current.getAttribute('data-veo-tag') || null,\n });\n current = current.parentElement;\n depth++;\n }\n\n return ancestors;\n}\n\n/** Construye el payload completo para el evento `$autocapture`. */\nexport function buildAutocapturePayload(\n eventType: 'click' | 'submit' | 'change',\n element: Element,\n config: SerializeConfig & { captureAncestors: number },\n): AutocapturePayload {\n return {\n $event_type: eventType,\n $element: serializeElement(element, config),\n $ancestors: serializeAncestors(element, config.captureAncestors),\n $selector_path: buildSelectorPath(element, config.captureAncestors),\n $page_url: window.location.href,\n $page_path: window.location.pathname,\n };\n}\n","/**\n * Throttle por elemento: evita duplicar eventos del mismo target dentro de una\n * ventana de N ms. Usa un WeakMap para no retener elementos en memoria.\n */\nexport class ElementThrottle {\n private lastFired = new WeakMap<Element, number>();\n\n constructor(private readonly windowMs: number) {}\n\n /** Devuelve true si el elemento puede emitir ahora (y registra el disparo). */\n shouldFire(element: Element): boolean {\n const now = Date.now();\n const last = this.lastFired.get(element) ?? 0;\n\n if (now - last < this.windowMs) return false;\n\n this.lastFired.set(element, now);\n return true;\n }\n}\n","import type { VeoAutocaptureConfig, VeoClient } from '../../types';\nimport { hasDocument } from '../../utils/safe-env';\nimport { ClickQualityTracker } from './click-quality';\nimport { DEFAULT_AUTOCAPTURE_CONFIG, MAX_ANCESTORS } from './constants';\nimport { buildAutocapturePayload } from './element-serializer';\nimport { isElementBlocked } from './pii-guard';\nimport { ElementThrottle } from './throttle';\n\ntype AutocaptureEvent = 'click' | 'submit' | 'change';\n\n/**\n * Instala listeners delegados en `document` y traduce las interacciones del\n * usuario en eventos `$autocapture`. Nunca lanza hacia la app del cliente:\n * cada handler está envuelto en try/catch.\n */\nexport class DomListener {\n private readonly throttle: ElementThrottle;\n private readonly config: Required<VeoAutocaptureConfig>;\n private cleanups: Array<() => void> = [];\n private quality: ClickQualityTracker | null = null;\n\n constructor(\n private readonly client: VeoClient,\n config: VeoAutocaptureConfig,\n ) {\n const d = DEFAULT_AUTOCAPTURE_CONFIG;\n // Resolver el config de forma explícita: el merge por spread reintroduce\n // `| undefined` y no satisface `Required<VeoAutocaptureConfig>`.\n this.config = {\n enabled: config.enabled ?? d.enabled,\n captureClicks: config.captureClicks ?? d.captureClicks,\n captureSubmits: config.captureSubmits ?? d.captureSubmits,\n captureChanges: config.captureChanges ?? d.captureChanges,\n maskAllInputs: config.maskAllInputs ?? d.maskAllInputs,\n maskAllText: config.maskAllText ?? d.maskAllText,\n blockSelectors: config.blockSelectors ?? [],\n throttleMs: config.throttleMs ?? d.throttleMs,\n maxTextLength: config.maxTextLength ?? d.maxTextLength,\n captureElementMetadata: config.captureElementMetadata ?? d.captureElementMetadata,\n captureAncestors: Math.min(config.captureAncestors ?? d.captureAncestors, MAX_ANCESTORS),\n captureClickQuality: config.captureClickQuality ?? d.captureClickQuality,\n };\n this.throttle = new ElementThrottle(this.config.throttleMs);\n }\n\n install(): void {\n if (!hasDocument() || !this.config.enabled) return;\n\n if (this.config.captureClicks && this.config.captureClickQuality) {\n // Dead / rage / error clicks: mismo payload que el clic + extras.\n this.quality = new ClickQualityTracker((kind, element, extra) => {\n const payload = buildAutocapturePayload('click', element, this.config);\n this.client.track(kind, { ...payload, ...extra } as unknown as Record<string, unknown>);\n });\n this.quality.install();\n }\n if (this.config.captureClicks) this.attach('click', (e) => this.handleClick(e));\n if (this.config.captureSubmits) this.attach('submit', (e) => this.handleSubmit(e), true);\n if (this.config.captureChanges) this.attach('change', (e) => this.handleChange(e), true);\n }\n\n destroy(): void {\n for (const cleanup of this.cleanups) cleanup();\n this.cleanups = [];\n this.quality?.destroy();\n this.quality = null;\n }\n\n private attach(\n eventName: AutocaptureEvent,\n handler: (e: Event) => void,\n useCapture = false,\n ): void {\n const listener = (e: Event) => {\n // Solo eventos reales del usuario (los sintéticos tienen isTrusted=false).\n if (!e.isTrusted) return;\n try {\n handler(e);\n } catch {\n // Nunca romper la app del cliente; descartamos el evento silenciosamente.\n }\n };\n document.addEventListener(eventName, listener, useCapture);\n this.cleanups.push(() => document.removeEventListener(eventName, listener, useCapture));\n }\n\n private handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n // Subir hasta el elemento \"interesante\" (botón, link, [role], etc.).\n // Si NO hay ninguno (click en zona vacía/no interactiva, p. ej. <html>),\n // no emitimos: evita ruido y volumen innecesario de eventos.\n const meaningful = this.findMeaningfulAncestor(target);\n if (!meaningful) return;\n if (isElementBlocked(meaningful, this.config.blockSelectors)) return;\n // Calidad del clic ANTES del throttle: una ráfaga (rage) son clics repetidos.\n this.quality?.onClick(meaningful, event as MouseEvent);\n if (!this.throttle.shouldFire(meaningful)) return;\n\n this.emit('click', meaningful);\n }\n\n private handleSubmit(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element) || target.tagName.toLowerCase() !== 'form') return;\n if (isElementBlocked(target, this.config.blockSelectors)) return;\n if (!this.throttle.shouldFire(target)) return;\n\n this.emit('submit', target);\n }\n\n private handleChange(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const tag = target.tagName.toLowerCase();\n if (tag !== 'select' && tag !== 'input' && tag !== 'textarea') return;\n\n // Para text inputs el change sería spam/PII; solo checkbox/radio (y selects).\n if (\n target instanceof HTMLInputElement &&\n target.type !== 'checkbox' &&\n target.type !== 'radio'\n ) {\n return;\n }\n if (isElementBlocked(target, this.config.blockSelectors)) return;\n if (!this.throttle.shouldFire(target)) return;\n\n this.emit('change', target);\n }\n\n /** Busca hacia arriba un ancestro \"interactivo\". Devuelve null si no hay ninguno. */\n private findMeaningfulAncestor(element: Element): Element | null {\n let current: Element | null = element;\n let depth = 0;\n\n while (current && current !== document.documentElement && depth < 5) {\n const tag = current.tagName.toLowerCase();\n const isInteractive =\n tag === 'button' ||\n tag === 'a' ||\n tag === 'input' ||\n tag === 'select' ||\n tag === 'textarea' ||\n current.hasAttribute('data-veo-tag') ||\n current.hasAttribute('role') ||\n current.hasAttribute('onclick') ||\n (current instanceof HTMLElement && current.style.cursor === 'pointer');\n\n if (isInteractive) return current;\n current = current.parentElement;\n depth++;\n }\n\n return null;\n }\n\n private emit(eventType: AutocaptureEvent, element: Element): void {\n const payload = buildAutocapturePayload(eventType, element, this.config);\n this.client.track('$autocapture', payload as unknown as Record<string, unknown>);\n }\n}\n","import type { VeoAutocaptureConfig, VeoPlugin } from '../../types';\nimport { definePlugin } from '../plugin';\nimport { DomListener } from './dom-listener';\n\n/**\n * Plugin de autocaptura de eventos del DOM.\n * Captura clicks, submits y changes automáticamente y los emite como\n * eventos `track('$autocapture', …)` por la Queue del cliente.\n */\nexport function autocapturePlugin(config: VeoAutocaptureConfig = {}): VeoPlugin {\n let listener: DomListener | null = null;\n\n return definePlugin({\n name: 'autocapture',\n install(client) {\n listener = new DomListener(client, config);\n listener.install();\n },\n destroy() {\n listener?.destroy();\n listener = null;\n },\n });\n}\n\nexport { DomListener } from './dom-listener';\nexport type { AutocapturePayload } from './element-serializer';\n","import type { VeoPlugin } from '../types';\nimport { hasWindow } from '../utils/safe-env';\nimport { definePlugin } from './plugin';\n\n/**\n * Plugin que auto-emite `pageview` en cambios de ruta de una SPA.\n * Cubre `history.pushState`, `history.replaceState`, `popstate` y `hashchange`.\n */\nexport function spaRouterPlugin(): VeoPlugin {\n return definePlugin({\n name: 'spa-router',\n install(client) {\n if (!hasWindow()) return;\n\n // Pageview inicial.\n client.pageview();\n\n const fire = () => {\n // Diferir para que el router del host actualice location.pathname primero.\n queueMicrotask(() => client.pageview());\n };\n\n const origPushState = window.history.pushState;\n const origReplaceState = window.history.replaceState;\n\n window.history.pushState = function (\n this: History,\n ...args: Parameters<History['pushState']>\n ): void {\n origPushState.apply(this, args);\n fire();\n };\n\n window.history.replaceState = function (\n this: History,\n ...args: Parameters<History['replaceState']>\n ): void {\n origReplaceState.apply(this, args);\n fire();\n };\n\n window.addEventListener('popstate', fire);\n window.addEventListener('hashchange', fire);\n },\n });\n}\n","import type { VeoPlugin } from '../../types';\nimport { hasDocument, hasWindow } from '../../utils/safe-env';\nimport type { ThemeMode, ThemeSnapshot } from './types';\n\nexport type {\n DetectedColor,\n DetectedFont,\n DetectedPalette,\n ThemeColorRole,\n ThemeMode,\n ThemeSnapshot,\n} from './types';\n\n/**\n * El detector (pesado: muestreo del DOM, hojas de estilo, fuentes) vive en\n * `detect-theme.ts` y llega por carga perezosa; este archivo es solo el\n * planificador liviano que va en el core. NO importar `detect-theme` acá.\n */\nexport interface ThemeDetectorApi {\n detectTheme: (doc?: Document) => ThemeSnapshot | null;\n snapshotHash: (snapshot: ThemeSnapshot) => string;\n}\n\nexport interface ThemeDetectPluginConfig {\n apiUrl: string;\n apiKey: string;\n debug?: boolean;\n /** Trae el detector: `import()` dinámico (bundlers) o `<script>` (IIFE). */\n loadDetector: () => Promise<ThemeDetectorApi | null>;\n}\n\nconst STORAGE_PREFIX = 'veo_theme_';\n/** Como mucho un envío al día por navegador y por modo de color. */\nconst RESEND_AFTER_MS = 24 * 60 * 60 * 1000;\n/** Espera tras el `load`: la app termina de hidratar y pintar su UI real. */\nconst SETTLE_MS = 4000;\n/** Tope de detecciones por carga de página (una app puede tocar `<html class>` seguido). */\nconst MAX_RUNS_PER_PAGE = 4;\n\ninterface SentRecord {\n hash: string;\n at: number;\n}\nexport type SentState = Partial<Record<ThemeMode, SentRecord>>;\n\nfunction readState(key: string): SentState {\n try {\n const raw = localStorage.getItem(key);\n const parsed: unknown = raw ? JSON.parse(raw) : null;\n return parsed && typeof parsed === 'object' ? (parsed as SentState) : {};\n } catch {\n return {};\n }\n}\n\nfunction writeState(key: string, state: SentState): void {\n try {\n localStorage.setItem(key, JSON.stringify(state));\n } catch {\n // Sin storage (incógnito, cuota): se reintenta en la próxima carga.\n }\n}\n\n/**\n * Modo de color APARENTE, barato (sin tocar estilos): decide si vale la pena\n * descargar el detector. El modo real lo determina `detectTheme`.\n */\nexport function guessMode(doc: Document, prefersDark: boolean): ThemeMode {\n const hints = [\n doc.documentElement.className,\n doc.documentElement.dataset.theme,\n doc.documentElement.dataset.mode,\n doc.body?.className,\n ]\n .join(' ')\n .toLowerCase();\n if (/\\bdark\\b/.test(hints)) return 'dark';\n if (/\\blight\\b/.test(hints)) return 'light';\n return prefersDark ? 'dark' : 'light';\n}\n\n/** ¿Este modo ya se reportó hace menos de un día? Entonces ni se carga el detector. */\nexport function isFresh(state: SentState, mode: ThemeMode, now: number): boolean {\n const last = state[mode];\n return last !== undefined && now - last.at < RESEND_AFTER_MS;\n}\n\n/** ¿Hay que enviar? No, si es igual al último envío de ese modo y aún no pasó un día. */\nexport function shouldSendSnapshot(\n state: SentState,\n mode: ThemeMode,\n hash: string,\n now: number,\n): boolean {\n const last = state[mode];\n return !last || last.hash !== hash || now - last.at >= RESEND_AFTER_MS;\n}\n\n/**\n * Detecta el tema de la app (colores por modo + fuentes) y lo reporta al\n * backend para que el design system de OnUser arranque ya con la marca del\n * cliente. Corre en idle, después del `load`, y como mucho una vez al día por\n * navegador y modo; también cuando el usuario alterna claro/oscuro. Solo viajan\n * colores y nombres de fuentes. Best-effort: cualquier fallo se ignora.\n */\nexport function themeDetectPlugin(config: ThemeDetectPluginConfig): VeoPlugin {\n const storageKey = `${STORAGE_PREFIX}${config.apiKey.slice(-16) || 'default'}`;\n let observer: MutationObserver | null = null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let destroyed = false;\n let runs = 0;\n\n const run = async (): Promise<void> => {\n if (destroyed || runs >= MAX_RUNS_PER_PAGE) return;\n const prefersDark =\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-color-scheme: dark)').matches;\n const guess = guessMode(document, prefersDark);\n if (isFresh(readState(storageKey), guess, Date.now())) return;\n runs++;\n try {\n const detector = await config.loadDetector();\n if (!detector || destroyed) return;\n const snapshot = detector.detectTheme();\n if (!snapshot) return;\n const hash = detector.snapshotHash(snapshot);\n const state = readState(storageKey);\n const now = Date.now();\n const mark = (): void => {\n const record = { hash, at: Date.now() };\n state[snapshot.mode] = record;\n // Si el modo aparente no coincide con el real (la app ignora\n // prefers-color-scheme), se marca también: evita re-detectar en cada carga.\n state[guess] = state[guess] && guess !== snapshot.mode ? state[guess] : record;\n writeState(storageKey, state);\n };\n if (!shouldSendSnapshot(state, snapshot.mode, hash, now)) {\n mark();\n return;\n }\n if (config.debug) console.log('[veo] theme snapshot', snapshot);\n const res = await fetch(`${config.apiUrl}/v1/workspaces/theme-snapshot`, {\n method: 'POST',\n headers: { 'X-Api-Key': config.apiKey, 'Content-Type': 'application/json' },\n body: JSON.stringify(snapshot),\n credentials: 'omit',\n });\n if (res.ok) mark();\n } catch (err) {\n if (config.debug) console.warn('[veo] theme detect failed', err);\n }\n };\n\n const schedule = (delayMs: number): void => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n const idle = (window as unknown as { requestIdleCallback?: (cb: () => void) => void })\n .requestIdleCallback;\n if (typeof idle === 'function') idle(() => void run());\n else void run();\n }, delayMs);\n };\n\n return {\n name: 'theme-detect',\n install() {\n if (!hasWindow() || !hasDocument()) return;\n if (document.readyState === 'complete') schedule(SETTLE_MS);\n else window.addEventListener('load', () => schedule(SETTLE_MS), { once: true });\n // El usuario alternó claro/oscuro: se detecta el nuevo modo en vivo.\n if (typeof MutationObserver === 'function') {\n observer = new MutationObserver(() => schedule(1500));\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class', 'data-theme', 'data-mode'],\n });\n }\n },\n destroy() {\n destroyed = true;\n observer?.disconnect();\n if (timer) clearTimeout(timer);\n },\n };\n}\n","/**\n * Genera un UUID v7 (timestamp-based, ordenable cronológicamente).\n * Spec: RFC 9562.\n *\n * Formato: tttttttt-tttt-7xxx-yxxx-xxxxxxxxxxxx\n * - 48 bits de timestamp (ms desde epoch)\n * - 4 bits de versión (7)\n * - 2 bits de variante (10)\n * - 74 bits aleatorios\n */\nexport function uuidv7(): string {\n const timestamp = Date.now();\n const timeHex = timestamp.toString(16).padStart(12, '0');\n\n // 10 bytes aleatorios para los 74 bits de entropía (+ bits de versión/variante).\n const random = new Uint8Array(10);\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n crypto.getRandomValues(random);\n } else {\n // Fallback inseguro pero funcional (no debería ocurrir en browsers modernos).\n for (let i = 0; i < random.length; i++) {\n random[i] = Math.floor(Math.random() * 256);\n }\n }\n\n // Set version (7) en el primer nibble del 3er grupo.\n random[0] = ((random[0] ?? 0) & 0x0f) | 0x70;\n // Set variant (10) en los 2 bits altos del 4to grupo.\n random[2] = ((random[2] ?? 0) & 0x3f) | 0x80;\n\n const hex = Array.from(random, (b) => b.toString(16).padStart(2, '0')).join('');\n\n return [\n timeHex.slice(0, 8),\n timeHex.slice(8, 12),\n hex.slice(0, 4),\n hex.slice(4, 8),\n hex.slice(8, 20),\n ].join('-');\n}\n","import type { Transport } from './transport';\n\nexport interface QueueConfig {\n transport: Transport;\n flushIntervalMs: number;\n batchSize: number;\n maxRetries?: number;\n onError?: (error: Error) => void;\n}\n\nconst RETRY_MAX_DELAY_MS = 30000;\n\n/**\n * Buffer de eventos con envío en batch, flush por intervalo o por tamaño, y\n * reintentos con backoff exponencial ante fallos de red. Los eventos que fallan\n * se re-encolan al inicio para preservar el orden.\n */\nexport class Queue<T = unknown> {\n private buffer: T[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n private retryCount = 0;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private readonly config: QueueConfig) {\n this.startTimer();\n }\n\n /** Encola un evento; dispara flush si se alcanza `batchSize`. */\n add(item: T): void {\n this.buffer.push(item);\n if (this.buffer.length >= this.config.batchSize) {\n void this.flush();\n }\n }\n\n /** Flush manual vía `fetch`. Resuelve cuando termina (los retries son diferidos). */\n async flush(): Promise<void> {\n if (this.flushing || this.buffer.length === 0) return;\n\n this.flushing = true;\n const batch = this.buffer.splice(0, this.buffer.length);\n\n try {\n await this.config.transport.send('/v1/events', { events: batch });\n this.retryCount = 0;\n } catch (error) {\n // Re-encolar al INICIO para preservar el orden cronológico.\n this.buffer.unshift(...batch);\n this.scheduleRetry();\n this.config.onError?.(error as Error);\n } finally {\n this.flushing = false;\n }\n }\n\n /** Flush síncrono vía `sendBeacon`, para `pagehide`/`visibilitychange`. */\n flushBeacon(): void {\n if (this.buffer.length === 0) return;\n const batch = this.buffer.splice(0, this.buffer.length);\n const success = this.config.transport.sendBeacon('/v1/events', { events: batch });\n if (!success) {\n // La página se está cerrando; re-encolar es poco útil pero evita pérdida si no se cierra.\n this.buffer.unshift(...batch);\n }\n }\n\n /** Detiene timers internos. Llamar al destruir el cliente. */\n destroy(): void {\n if (this.timer) clearInterval(this.timer);\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.timer = null;\n this.retryTimer = null;\n }\n\n private startTimer(): void {\n this.timer = setInterval(() => {\n void this.flush();\n }, this.config.flushIntervalMs);\n }\n\n private scheduleRetry(): void {\n const maxRetries = this.config.maxRetries ?? 3;\n if (this.retryCount >= maxRetries) {\n this.retryCount = 0;\n return;\n }\n\n this.retryCount++;\n // Backoff exponencial: 1s, 2s, 4s, 8s... con tope de 30s, MÁS jitter.\n // Sin jitter, ante un 5xx del backend TODOS los clientes reintentan en\n // lockstep (1s, 2s, 4s…) y amplifican el pico justo cuando está degradado.\n // Equal jitter: mitad fija + mitad aleatoria → desincroniza la horda.\n const base = Math.min(1000 * 2 ** (this.retryCount - 1), RETRY_MAX_DELAY_MS);\n const delayMs = base / 2 + Math.random() * (base / 2);\n\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.retryTimer = setTimeout(() => {\n void this.flush();\n }, delayMs);\n }\n}\n","import { uuidv7 } from '../utils/uuid';\nimport type { StorageAdapter } from './storage';\n\nconst ANONYMOUS_ID_KEY = 'anonymous_user_id';\nconst END_USER_ID_KEY = 'end_user_id';\nconst SESSION_ID_KEY = 'session_id';\nconst SESSION_LAST_ACTIVE_KEY = 'session_last_active';\nconst SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutos\n\n/**\n * Gestiona la identidad triple del SDK:\n * - `anonymousId`: persiste indefinidamente (≥ 1 año).\n * - `endUserId`: presente tras `identify()`.\n * - `sessionId`: se renueva tras 30 min de inactividad.\n */\nexport class Session {\n private _anonymousId: string;\n private _sessionId: string;\n private _endUserId: string | null = null;\n\n constructor(private readonly storage: StorageAdapter) {\n this._anonymousId = this.loadOrCreateAnonymousId();\n this._sessionId = this.loadOrCreateSession();\n // Restaurar la identidad persistida: sin esto el SDK \"olvida\" al usuario\n // en cada recarga y los eventos posteriores caen al anonymous_id hasta\n // que la app vuelva a llamar identify(). Persistimos end_user_id en\n // setEndUserId(), así que también hay que rehidratarlo aquí.\n this._endUserId = this.storage.get(END_USER_ID_KEY);\n }\n\n get anonymousId(): string {\n return this._anonymousId;\n }\n\n get sessionId(): string {\n return this._sessionId;\n }\n\n get endUserId(): string | null {\n return this._endUserId;\n }\n\n /** ID a usar como visitor en eventos (end_user_id si está identificado, si no anonymous). */\n get effectiveUserId(): string {\n return this._endUserId ?? this._anonymousId;\n }\n\n setEndUserId(id: string): void {\n this._endUserId = id;\n this.storage.set(END_USER_ID_KEY, id);\n }\n\n /** Renueva el timestamp de actividad. Si pasaron > 30 min, genera nueva sesión. */\n touch(): void {\n const lastActive = this.storage.get(SESSION_LAST_ACTIVE_KEY);\n const now = Date.now();\n\n if (lastActive && now - Number.parseInt(lastActive, 10) > SESSION_TIMEOUT_MS) {\n this._sessionId = uuidv7();\n this.storage.set(SESSION_ID_KEY, this._sessionId);\n }\n\n this.storage.set(SESSION_LAST_ACTIVE_KEY, String(now));\n }\n\n /** Limpia la identidad (reset) pero conserva el anonymous_id. */\n reset(): void {\n this._endUserId = null;\n this.storage.remove(END_USER_ID_KEY);\n // Regenerar sesión.\n this._sessionId = uuidv7();\n this.storage.set(SESSION_ID_KEY, this._sessionId);\n this.storage.set(SESSION_LAST_ACTIVE_KEY, String(Date.now()));\n }\n\n private loadOrCreateAnonymousId(): string {\n let id = this.storage.get(ANONYMOUS_ID_KEY);\n if (!id) {\n id = uuidv7();\n this.storage.set(ANONYMOUS_ID_KEY, id);\n }\n return id;\n }\n\n private loadOrCreateSession(): string {\n const existing = this.storage.get(SESSION_ID_KEY);\n const lastActive = this.storage.get(SESSION_LAST_ACTIVE_KEY);\n\n if (existing && lastActive) {\n const elapsed = Date.now() - Number.parseInt(lastActive, 10);\n if (elapsed < SESSION_TIMEOUT_MS) {\n return existing;\n }\n }\n\n const newId = uuidv7();\n this.storage.set(SESSION_ID_KEY, newId);\n this.storage.set(SESSION_LAST_ACTIVE_KEY, String(Date.now()));\n return newId;\n }\n}\n","import { hasDocument, hasLocalStorage } from '../utils/safe-env';\n\n/**\n * Contrato común de todos los backends de almacenamiento persistente.\n * Las claves se guardan internamente con el prefijo `veo:`.\n */\nexport interface StorageAdapter {\n get(key: string): string | null;\n set(key: string, value: string, options?: { ttlMs?: number }): void;\n remove(key: string): void;\n /** Borra únicamente las claves del SDK (prefijo `veo:`). */\n clear(): void;\n}\n\nconst STORAGE_PREFIX = 'veo:';\n/** TTL por defecto para cookies (1 año), satisface la persistencia del anonymous id. */\nconst ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;\n\n/** Backend basado en `localStorage`. Persistencia indefinida (ignora `ttlMs`). */\nclass LocalStorageAdapter implements StorageAdapter {\n get(key: string): string | null {\n return localStorage.getItem(STORAGE_PREFIX + key);\n }\n\n set(key: string, value: string): void {\n try {\n localStorage.setItem(STORAGE_PREFIX + key, value);\n } catch {\n // Cuota llena o storage bloqueado: ignorar silenciosamente.\n }\n }\n\n remove(key: string): void {\n localStorage.removeItem(STORAGE_PREFIX + key);\n }\n\n clear(): void {\n const toRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith(STORAGE_PREFIX)) toRemove.push(key);\n }\n for (const key of toRemove) localStorage.removeItem(key);\n }\n}\n\n/** Lee y trocea `document.cookie`. Solo se invoca cuando hay `document`. */\nfunction readCookies(): string[] {\n const raw = document.cookie;\n return raw === '' ? [] : raw.split('; ');\n}\n\n/** Backend basado en cookies de primer nivel. Usa `ttlMs` (default 1 año). */\nclass CookieAdapter implements StorageAdapter {\n get(key: string): string | null {\n const name = `${STORAGE_PREFIX}${key}=`;\n for (const cookie of readCookies()) {\n if (cookie.startsWith(name)) {\n return decodeURIComponent(cookie.slice(name.length));\n }\n }\n return null;\n }\n\n set(key: string, value: string, options?: { ttlMs?: number }): void {\n const maxAgeSec = Math.floor((options?.ttlMs ?? ONE_YEAR_MS) / 1000);\n const secure =\n typeof location !== 'undefined' && location.protocol === 'https:' ? '; Secure' : '';\n // biome-ignore lint/suspicious/noDocumentCookie: necesitamos escritura síncrona y cero deps; la Cookie Store API es async y no universal.\n document.cookie = `${STORAGE_PREFIX}${key}=${encodeURIComponent(\n value,\n )}; Path=/; Max-Age=${maxAgeSec}; SameSite=Lax${secure}`;\n }\n\n remove(key: string): void {\n // biome-ignore lint/suspicious/noDocumentCookie: ver set(); expiramos la cookie con Max-Age=0.\n document.cookie = `${STORAGE_PREFIX}${key}=; Path=/; Max-Age=0; SameSite=Lax`;\n }\n\n clear(): void {\n for (const cookie of readCookies()) {\n const eq = cookie.indexOf('=');\n const name = eq === -1 ? cookie : cookie.slice(0, eq);\n if (name.startsWith(STORAGE_PREFIX)) {\n this.remove(name.slice(STORAGE_PREFIX.length));\n }\n }\n }\n}\n\n/** Backend en memoria. Fallback cuando no hay browser storage (SSR, incógnito). */\nclass MemoryAdapter implements StorageAdapter {\n private store = new Map<string, string>();\n\n get(key: string): string | null {\n return this.store.get(key) ?? null;\n }\n\n set(key: string, value: string): void {\n this.store.set(key, value);\n }\n\n remove(key: string): void {\n this.store.delete(key);\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n\n/**\n * Crea el adapter de almacenamiento, respetando la preferencia del usuario y\n * cayendo a la mejor alternativa disponible si la preferida no existe.\n */\nexport function createStorage(\n preferred: 'localStorage' | 'cookie' | 'memory' = 'localStorage',\n): StorageAdapter {\n if (preferred === 'localStorage' && hasLocalStorage()) return new LocalStorageAdapter();\n if (preferred === 'cookie' && hasDocument()) return new CookieAdapter();\n if (preferred === 'memory') return new MemoryAdapter();\n\n // Cadena de fallback.\n if (hasLocalStorage()) return new LocalStorageAdapter();\n if (hasDocument()) return new CookieAdapter();\n return new MemoryAdapter();\n}\n","import { hasNavigatorSendBeacon } from '../utils/safe-env';\n\nexport interface TransportConfig {\n apiUrl: string;\n apiKey: string;\n sdkVersion: string;\n timeoutMs?: number;\n}\n\n/** Error de transporte con el código HTTP asociado (0 si fue un fallo de red). */\nexport class TransportError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n ) {\n super(message);\n this.name = 'TransportError';\n }\n}\n\n/**\n * Capa de red del SDK. Envía JSON al backend vía `fetch` (con timeout) y\n * ofrece `sendBeacon` para descargas fiables al cerrar la página.\n */\nexport class Transport {\n constructor(private readonly config: TransportConfig) {}\n\n /** Envío normal con `fetch`. Lanza `TransportError` si la respuesta no es OK. */\n async send<T = unknown>(path: string, body: unknown): Promise<T> {\n const url = `${this.config.apiUrl}${path}`;\n const controller = new AbortController();\n const timeoutMs = this.config.timeoutMs ?? 10000;\n // Abortamos con un motivo explícito para que el log sea claro\n // (`TimeoutError`) en vez del confuso \"signal is aborted without reason\".\n const timeoutId = setTimeout(\n () =>\n controller.abort(new DOMException(`Veo request timeout (${timeoutMs}ms)`, 'TimeoutError')),\n timeoutMs,\n );\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Api-Key': this.config.apiKey,\n 'X-Sdk-Version': this.config.sdkVersion,\n },\n body: JSON.stringify(body),\n // NO usar `keepalive: true` en los flushes normales: tiene límites\n // estrictos del navegador (cuota de requests/64KB) y produce abortos\n // espurios cuando hay varios envíos seguidos. El envío fiable al cerrar\n // la página ya lo cubre `sendBeacon()` (ver Queue.flushBeacon).\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new TransportError(`HTTP ${response.status}`, response.status);\n }\n\n return (await response.json()) as T;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Envío con `navigator.sendBeacon`. Fire-and-forget, pensado para `pagehide`.\n * Como sendBeacon no admite headers, la API key viaja por query string.\n */\n sendBeacon(path: string, body: unknown): boolean {\n if (!hasNavigatorSendBeacon()) return false;\n\n const url = new URL(`${this.config.apiUrl}${path}`);\n url.searchParams.set('key', this.config.apiKey);\n url.searchParams.set('v', this.config.sdkVersion);\n\n const blob = new Blob([JSON.stringify(body)], { type: 'application/json' });\n return navigator.sendBeacon(url.toString(), blob);\n }\n}\n","import type { ActionPayload, ActionType, IdentifyRequest } from '../contract/v1';\nimport { DEFAULT_FLUSH_BATCH_SIZE, DEFAULT_FLUSH_INTERVAL_MS, SDK_VERSION } from '../contract/v1';\nimport type {\n VeoClient,\n VeoClientEventListener,\n VeoClientEventName,\n VeoClientEvents,\n VeoConfig,\n VeoOrganization,\n VeoPlugin,\n VeoVisitor,\n} from '../types';\nimport { hasDocument, hasWindow } from '../utils/safe-env';\nimport { uuidv7 } from '../utils/uuid';\nimport { resolveApiUrl } from './api-url';\nimport { Queue } from './queue';\nimport { Session } from './session';\nimport { createStorage, type StorageAdapter } from './storage';\nimport { Transport } from './transport';\n\nconst ORGANIZATION_ID_KEY = 'organization_id';\nconst END_USER_ID_KEY = 'end_user_id';\nconst IDENTIFY_SIG_KEY = 'identify_signature';\n\n/**\n * `JSON.stringify` con claves ordenadas (recursivo) para que la firma de\n * identidad sea estable sin importar el orden en que la app arme el objeto\n * de traits/attributes. Sin esto, `{a,b}` y `{b,a}` darían firmas distintas\n * y el identify se reenviaría sin que nada haya cambiado.\n */\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value) ?? 'null';\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`;\n const entries = Object.keys(value as Record<string, unknown>)\n .sort()\n .map((k) => `${JSON.stringify(k)}:${stableStringify((value as Record<string, unknown>)[k])}`);\n return `{${entries.join(',')}}`;\n}\n\n/** Campos opcionales que cada API pública aporta al construir el evento. */\ninterface EnqueueInput {\n actionType: ActionType;\n actionName?: string;\n pageUrl?: string;\n pagePath?: string;\n pageTitle?: string;\n pageReferrer?: string;\n actionProperties?: Record<string, unknown>;\n}\n\n/**\n * Cliente principal del SDK. Expone la API pública (`identify`, `track`,\n * `pageview`, `reset`, `flush`, `use`). Toda la API salvo `flush()` es síncrona:\n * los eventos se encolan y la llamada retorna de inmediato.\n */\nexport class Client implements VeoClient {\n private readonly transport: Transport;\n private readonly storage: StorageAdapter;\n private readonly session: Session;\n private readonly queue: Queue<ActionPayload>;\n private readonly plugins: VeoPlugin[] = [];\n private currentOrganizationId: string | null = null;\n private readonly listeners: {\n [E in VeoClientEventName]: Set<VeoClientEventListener<E>>;\n } = {\n pageview: new Set(),\n identify: new Set(),\n };\n\n constructor(private readonly config: VeoConfig) {\n if (!config.apiKey) throw new Error('apiKey is required');\n\n this.storage = createStorage(config.storage ?? 'localStorage');\n this.session = new Session(this.storage);\n\n this.transport = new Transport({\n apiKey: config.apiKey,\n apiUrl: resolveApiUrl(config).replace(/\\/$/, ''),\n sdkVersion: SDK_VERSION,\n });\n\n this.queue = new Queue<ActionPayload>({\n transport: this.transport,\n flushIntervalMs: config.flushInterval ?? DEFAULT_FLUSH_INTERVAL_MS,\n batchSize: config.flushBatchSize ?? DEFAULT_FLUSH_BATCH_SIZE,\n onError: (err) => {\n if (config.debug) console.error('[veo] flush error:', err);\n },\n });\n\n // Rehidratar identidad persistida.\n const persistedUserId = this.storage.get(END_USER_ID_KEY);\n if (persistedUserId) this.session.setEndUserId(persistedUserId);\n\n const persistedOrgId = this.storage.get(ORGANIZATION_ID_KEY);\n if (persistedOrgId) this.currentOrganizationId = persistedOrgId;\n\n this.setupUnloadHandlers();\n\n if (config.debug) {\n console.log('[veo] initialized', {\n anonymousId: this.session.anonymousId,\n sessionId: this.session.sessionId,\n endUserId: this.session.endUserId,\n });\n }\n }\n\n identify(payload: { visitor: VeoVisitor; organization?: VeoOrganization }): void {\n const { visitor, organization } = payload;\n\n // Idempotencia: si ya estamos identificados como este visitor y ni los\n // traits ni la organización cambiaron, no reenviamos. Esto evita el spam\n // de identify cuando la app lo llama en cada carga/navegación (un patrón\n // común y recomendado): el SDK absorbe la repetición en vez de generar un\n // evento `identify` y un POST /v1/identify por cada render.\n const signature = stableStringify({\n id: visitor.id,\n traits: visitor.traits ?? {},\n org: organization ? { id: organization.id, attributes: organization.attributes ?? {} } : null,\n });\n if (this.session.endUserId === visitor.id && this.storage.get(IDENTIFY_SIG_KEY) === signature) {\n if (this.config.debug) console.debug('[veo] identify: sin cambios, omitido');\n return;\n }\n\n // Capturar el anonymous previo ANTES de mutar la identidad, para el merge en backend.\n const previousAnonymousId =\n this.session.endUserId === null ? this.session.anonymousId : undefined;\n\n this.session.setEndUserId(visitor.id);\n if (organization) {\n this.currentOrganizationId = organization.id;\n this.storage.set(ORGANIZATION_ID_KEY, organization.id);\n }\n\n // 1. Upsert de traits/attributes en /v1/identify (fire-and-forget).\n const endUser: IdentifyRequest['endUser'] = {\n id: visitor.id,\n traits: visitor.traits ?? {},\n ...(previousAnonymousId !== undefined ? { anonymousId: previousAnonymousId } : {}),\n };\n const body: IdentifyRequest = {\n endUser,\n ...(organization\n ? { organization: { id: organization.id, attributes: organization.attributes ?? {} } }\n : {}),\n };\n void this.transport.send('/v1/identify', body).catch((err) => {\n if (this.config.debug) console.error('[veo] identify failed:', err);\n });\n\n // 2. Registrar el evento \"identify\" en el log de acciones.\n this.enqueue({\n actionType: 'identify',\n actionProperties: {\n traits: visitor.traits,\n organizationAttributes: organization?.attributes,\n },\n });\n\n this.storage.set(IDENTIFY_SIG_KEY, signature);\n\n this.emit('identify', { endUserId: visitor.id, sessionId: this.session.sessionId });\n }\n\n track(name: string, properties?: Record<string, unknown>): void {\n if (!name || typeof name !== 'string') {\n if (this.config.debug) console.error('[veo] track: name is required');\n return;\n }\n this.enqueue({\n actionType: 'track',\n actionName: name,\n ...(properties !== undefined ? { actionProperties: properties } : {}),\n });\n }\n\n pageview(path?: string): void {\n if (!hasDocument()) return;\n\n const url = window.location.href;\n const pagePath = path ?? window.location.pathname;\n\n this.enqueue({\n actionType: 'pageview',\n pageUrl: url,\n pagePath,\n pageTitle: document.title,\n pageReferrer: document.referrer,\n });\n\n this.emit('pageview', {\n url,\n path: pagePath,\n sessionId: this.session.sessionId,\n endUserId: this.session.endUserId,\n });\n }\n\n reset(): void {\n this.session.reset();\n this.currentOrganizationId = null;\n this.storage.remove(ORGANIZATION_ID_KEY);\n this.storage.remove(END_USER_ID_KEY);\n this.storage.remove(IDENTIFY_SIG_KEY);\n }\n\n flush(): Promise<void> {\n return this.queue.flush();\n }\n\n use(plugin: VeoPlugin): VeoClient {\n this.plugins.push(plugin);\n plugin.install(this);\n return this;\n }\n\n getEndUserId(): string | null {\n return this.session.endUserId;\n }\n\n getAnonymousId(): string {\n return this.session.anonymousId;\n }\n\n getSessionId(): string {\n return this.session.sessionId;\n }\n\n /**\n * Suscribe `listener` a `event`. Devuelve una función para desuscribir.\n * Los errores en listeners se logean en debug mode pero NO se propagan\n * (un plugin no debe poder romper a otro).\n */\n on<E extends VeoClientEventName>(event: E, listener: VeoClientEventListener<E>): () => void {\n this.listeners[event].add(listener);\n return () => {\n this.listeners[event].delete(listener);\n };\n }\n\n private emit<E extends VeoClientEventName>(event: E, payload: VeoClientEvents[E]): void {\n for (const listener of this.listeners[event]) {\n try {\n listener(payload);\n } catch (err) {\n if (this.config.debug) console.error(`[veo] listener for '${event}' failed:`, err);\n }\n }\n }\n\n /**\n * Construye el evento completo y lo agrega a la queue. Omite los campos\n * opcionales no definidos (exigido por `exactOptionalPropertyTypes`).\n * @internal\n */\n private enqueue(input: EnqueueInput): void {\n this.session.touch();\n\n const organizationId = this.currentOrganizationId ?? undefined;\n const pageUrl = input.pageUrl ?? (hasWindow() ? window.location.href : undefined);\n const pagePath = input.pagePath ?? (hasWindow() ? window.location.pathname : undefined);\n const pageTitle = input.pageTitle ?? (hasDocument() ? document.title : undefined);\n const pageReferrer = input.pageReferrer ?? (hasDocument() ? document.referrer : undefined);\n\n const event: ActionPayload = {\n actionId: uuidv7(),\n endUserId: this.session.effectiveUserId,\n sessionId: this.session.sessionId,\n actionType: input.actionType,\n occurredAt: new Date().toISOString(),\n ...(organizationId !== undefined ? { organizationId } : {}),\n ...(input.actionName !== undefined ? { actionName: input.actionName } : {}),\n ...(pageUrl !== undefined ? { pageUrl } : {}),\n ...(pagePath !== undefined ? { pagePath } : {}),\n ...(pageTitle !== undefined ? { pageTitle } : {}),\n ...(pageReferrer !== undefined ? { pageReferrer } : {}),\n ...(input.actionProperties !== undefined ? { actionProperties: input.actionProperties } : {}),\n };\n\n this.queue.add(event);\n }\n\n private setupUnloadHandlers(): void {\n if (!hasWindow()) return;\n\n window.addEventListener('pagehide', () => this.queue.flushBeacon());\n window.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n this.queue.flushBeacon();\n }\n });\n }\n}\n","import { autocapturePlugin } from '../plugins/autocapture';\nimport { spaRouterPlugin } from '../plugins/spa-router';\nimport { type ThemeDetectorApi, themeDetectPlugin } from '../plugins/theme-detect';\nimport type { VeoClient, VeoConfig } from '../types';\nimport { resolveApiUrl } from './api-url';\nimport { isBuilderMode, maybeLoadBuilder } from './builder-loader';\nimport { Client } from './client';\n\n/**\n * Setup común del cliente, compartido por el entry ESM/CJS (`index.ts`, guías\n * estáticas) y el IIFE (`veo.ts`, guías perezosas). NO importa el plugin de\n * guías: la instalación va por el callback `onGuides`, así el bundle IIFE puede\n * quedar sin los renderers.\n *\n * El detector de tema también llega por callback (`loadThemeDetector`): el core\n * solo lleva el planificador; el detector se descarga como mucho una vez al día.\n *\n * Hace: client + spa-router + autocapture, instala guías vía callback, asigna\n * `window.veo` drenando la cola del snippet, y dispara el loader del builder.\n */\nexport function setupClient(\n config: VeoConfig,\n onGuides: (client: VeoClient) => void,\n loadBuilder?: () => Promise<unknown>,\n loadThemeDetector?: () => Promise<ThemeDetectorApi | null>,\n): VeoClient {\n const client = new Client(config);\n\n client.use(spaRouterPlugin());\n\n if (config.autocapture !== false) {\n const autocaptureConfig = typeof config.autocapture === 'object' ? config.autocapture : {};\n client.use(autocapturePlugin(autocaptureConfig));\n }\n\n // Tema de la app (colores + fuentes) para el design system. En modo builder\n // no corre: ahí la página tiene encima el chrome del editor.\n if (config.detectTheme !== false && loadThemeDetector && !isBuilderMode()) {\n client.use(\n themeDetectPlugin({\n apiUrl: resolveApiUrl(config),\n apiKey: config.apiKey,\n loadDetector: loadThemeDetector,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n }\n\n // Guías (opt-in): el caller decide instalarlas sync (bundler) o lazy (IIFE).\n onGuides(client);\n\n if (typeof window !== 'undefined') {\n const stub = (window as unknown as { veo?: { _q?: unknown[][] } }).veo;\n const pending = stub?._q ?? [];\n\n (window as unknown as { veo: VeoClient }).veo = client;\n\n for (const entry of pending) {\n const [method, args] = entry;\n if (method === 'init') continue; // ya inicializado\n const fn = (client as unknown as Record<string, (...a: unknown[]) => unknown>)[\n method as string\n ];\n if (typeof fn === 'function') {\n try {\n fn.apply(client, Array.from(args as ArrayLike<unknown>));\n } catch (err) {\n if (config.debug) console.error('[veo] drain error:', err);\n }\n }\n }\n\n maybeLoadBuilder({\n ...(config.builderUrl !== undefined ? { builderUrl: config.builderUrl } : {}),\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n ...(config.apiKey !== undefined ? { apiKey: config.apiKey } : {}),\n apiUrl: resolveApiUrl(config),\n ...(loadBuilder ? { loadBuilder } : {}),\n });\n }\n\n return client;\n}\n","import type { ThemeDetectorApi } from '../plugins/theme-detect';\nimport { hasDocument, hasWindow } from '../utils/safe-env';\n\n/**\n * Carga perezosa del detector de tema (`veo-theme.js`) en el build IIFE: inyecta\n * el `<script>` derivando la URL del que cargó `veo.js`. Devuelve `null` si no\n * se puede (sin DOM, URL no derivable, error de red): la detección es\n * best-effort y nunca debe afectar a la app.\n */\nexport function loadThemeDetector(opts: {\n themeUrl?: string;\n debug?: boolean;\n}): Promise<ThemeDetectorApi | null> {\n if (!hasWindow() || !hasDocument()) return Promise.resolve(null);\n const win = window as unknown as { veoTheme?: ThemeDetectorApi };\n if (win.veoTheme) return Promise.resolve(win.veoTheme);\n\n const url = opts.themeUrl ?? deriveThemeUrl();\n if (!url) {\n if (opts.debug) console.warn('[veo] no pude resolver la URL de veo-theme.js');\n return Promise.resolve(null);\n }\n return new Promise((resolve) => {\n const script = document.createElement('script');\n script.src = url;\n script.async = true;\n script.addEventListener('load', () => resolve(win.veoTheme ?? null));\n script.addEventListener('error', () => {\n if (opts.debug) console.error('[veo] no pude cargar', url);\n resolve(null);\n });\n document.head.appendChild(script);\n });\n}\n\n/** Deriva `veo-theme.js` del `<script>` que cargó `veo.js`. */\nfunction deriveThemeUrl(): string | null {\n const scripts = document.querySelectorAll<HTMLScriptElement>('script[src]');\n for (const script of Array.from(scripts)) {\n if (/\\bveo(\\.min)?\\.js(\\?.*)?$/.test(script.src)) {\n return script.src.replace(/\\bveo(\\.min)?\\.js/, 'veo-theme$1.js');\n }\n }\n return null;\n}\n","/**\n * Entry IIFE (`veo.js`, global `window.veo`). Igual que `index.ts` pero las\n * GUÍAS se cargan PEREZOSAMENTE (bundle `veo-guides.js`) — solo con\n * `guides:true` o al usar `veo.preview()`. Así `veo.js` queda chico (core +\n * spa-router + autocapture); los renderers + Floating UI van aparte.\n *\n * Los consumidores por bundler usan `@veo/sdk` (entry `index.ts`, estático).\n */\nimport { resolveApiUrl } from './core/api-url';\nimport { isBuilderMode } from './core/builder-loader';\nimport { loadGuides, type VeoGuidesApi } from './core/guides-loader';\nimport { getPreviewToken } from './core/preview-loader';\nimport { setupClient } from './core/setup';\nimport { loadThemeDetector } from './core/theme-loader';\nimport type { PreviewGuideInput, PreviewHandle, PreviewResult } from './plugins/guides';\nimport type { VeoClient, VeoConfig } from './types';\n\nexport { SDK_VERSION } from './contract/v1';\nexport { Client } from './core/client';\nexport { autocapturePlugin } from './plugins/autocapture';\nexport { definePlugin } from './plugins/plugin';\nexport { spaRouterPlugin } from './plugins/spa-router';\nexport type {\n VeoAutocaptureConfig,\n VeoClient,\n VeoConfig,\n VeoOrganization,\n VeoPlugin,\n VeoVisitor,\n} from './types';\n\n/** Inicializa el SDK (IIFE). Las guías se cargan perezosamente. */\nexport function init(config: VeoConfig): VeoClient {\n const apiUrl = resolveApiUrl(config);\n return setupClient(\n config,\n (client) => {\n const ensureGuides = (): Promise<VeoGuidesApi | null> =>\n loadGuides({\n ...(config.guidesUrl !== undefined ? { guidesUrl: config.guidesUrl } : {}),\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n });\n\n // Plugin runtime (guides:true): cargar el bundle e instalar al resolver.\n // En modo builder o preview-por-link NO se instala: ahí pinta la preview,\n // y el runtime duplicaría/taparía con las guías live.\n const previewToken = getPreviewToken();\n if (config.guides === true && !isBuilderMode() && previewToken === null) {\n void ensureGuides().then((guides) => {\n if (!guides) return;\n client.use(\n guides.guidesPlugin({\n apiUrl,\n apiKey: config.apiKey,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n });\n }\n\n // Modo preview-por-link (`?veoPreview=<token>`): cargar el bundle de guías\n // y renderizar la guía del token como vista previa sobre la app real.\n if (previewToken !== null) {\n void ensureGuides().then((guides) =>\n guides?.runPreviewMode({\n apiKey: config.apiKey,\n apiUrl,\n token: previewToken,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n }\n\n // `veo.preview()` / `veo.closePreview()` cargan las guías on-demand y\n // mantienen el shape { close, ready } aunque el bundle resuelva async.\n (client as unknown as Record<string, unknown>).preview = (\n input: PreviewGuideInput,\n ): PreviewHandle => {\n let inner: PreviewHandle | null = null;\n const ready: Promise<PreviewResult> = ensureGuides().then((guides) => {\n if (!guides) return { rendered: false };\n inner = guides.previewGuide(input);\n return inner.ready;\n });\n return { close: () => inner?.close(), ready, host: () => inner?.host() ?? null };\n };\n (client as unknown as Record<string, unknown>).closePreview = (): void => {\n void ensureGuides().then((guides) => guides?.closeGuidePreview());\n };\n },\n undefined,\n // Detector de tema: bundle aparte (`veo-theme.js`), solo cuando toca detectar.\n () =>\n loadThemeDetector({\n ...(config.themeUrl !== undefined ? { themeUrl: config.themeUrl } : {}),\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/contract/v1.ts","../src/core/api-url.ts","../src/utils/safe-env.ts","../src/core/builder-constants.ts","../src/core/preview-loader.ts","../src/core/builder-token.ts","../src/core/builder-loader.ts","../src/core/guides-loader.ts","../src/plugins/plugin.ts","../src/plugins/autocapture/constants.ts","../src/plugins/autocapture/selector-builder.ts","../src/plugins/autocapture/click-quality.ts","../src/plugins/autocapture/pii-guard.ts","../src/plugins/autocapture/element-serializer.ts","../src/plugins/autocapture/throttle.ts","../src/plugins/autocapture/dom-listener.ts","../src/plugins/autocapture/index.ts","../src/plugins/spa-router.ts","../src/plugins/theme-detect/index.ts","../src/utils/uuid.ts","../src/core/queue.ts","../src/core/session.ts","../src/core/storage.ts","../src/core/transport.ts","../src/core/client.ts","../src/core/setup.ts","../src/core/theme-loader.ts","../src/veo.ts"],"names":["SDK_VERSION","DEFAULT_API_URL","resolveApiUrl","config","fromConfig","fromGlobal","hasWindow","hasDocument","hasLocalStorage","testKey","hasNavigatorSendBeacon","BUILDER_TOKEN_PARAM","BUILDER_ORIGIN_PARAM","BUILDER_PANEL_PARAM","BUILDER_PANEL_PATH_PARAM","BUILDER_GUIDE_PARAM","PREVIEW_TOKEN_PARAM","PREVIEW_TOKEN_KEY","session","getPreviewToken","fromUrl","value","store","isPreviewMode","CTX_KEY","LS_PREFIX","PERSIST_TTL_MS","local","lsKey","guide","persist","ctx","stored","readFreshFromLocal","best","i","key","raw","parsed","_savedAt","urlParams","search","hash","resolveBuilderContext","params","fromLocal","resolveBuilderToken","isBuilderMode","maybeLoadBuilder","opts","url","deriveBuilderUrl","script","err","scripts","cached","loadGuides","loadInternal","resolve","win","deriveGuidesUrl","done","existing","definePlugin","plugin","DEFAULT_AUTOCAPTURE_CONFIG","MAX_ANCESTORS","ALWAYS_BLOCK_SELECTORS","SENSITIVE_ATTRIBUTES","PRIORITY_ATTRIBUTES","HASHED_CLASS_PATTERNS","isHashedClass","className","pattern","filterHumanClasses","element","c","STABLE_ATTRIBUTES","MAX_ATTR_VALUE_LENGTH","cssEscape","escapeAttrValue","stableAttributeSelector","tag","attr","buildElementSelector","veoTag","classes","classPart","attrSelector","buildSelectorPath","maxAncestors","parts","current","depth","NO_DEAD_TAGS","MAX_ERROR_MESSAGE","HISTORY_MS","DEFAULTS","describeError","text","ClickQualityTracker","emit","options","on","type","handler","capture","e","b","event","now","obs","netAtClick","navAtClick","focusAtClick","hrefAtClick","skipDead","observer","reacted","anchor","href","clickedAt","deadline","check","source","message","cutoff","list","kept","o","el","obsList","fast","slow","isRage","burst","clicks","kind","extra","counts","h","origPush","origReplace","self","args","orig","p","res","proto","origSend","isElementBlocked","extraBlockSelectors","allBlockers","selector","isSensitiveAttribute","attrName","lower","safeGetText","maxLength","mask","tagName","trimmed","extractPriorityAttributes","result","serializeElement","rect","serializeAncestors","maxDepth","ancestors","buildAutocapturePayload","eventType","ElementThrottle","windowMs","last","DomListener","client","d","payload","cleanup","eventName","useCapture","listener","target","meaningful","autocapturePlugin","spaRouterPlugin","fire","origPushState","origReplaceState","STORAGE_PREFIX","RESEND_AFTER_MS","SETTLE_MS","MAX_RUNS_PER_PAGE","readState","writeState","state","guessMode","doc","prefersDark","hints","isFresh","mode","shouldSendSnapshot","themeDetectPlugin","storageKey","timer","destroyed","runs","run","guess","detector","snapshot","mark","record","schedule","delayMs","idle","uuidv7","timeHex","random","hex","Queue","item","batch","error","maxRetries","base","ANONYMOUS_ID_KEY","END_USER_ID_KEY","SESSION_ID_KEY","SESSION_LAST_ACTIVE_KEY","SESSION_TIMEOUT_MS","Session","storage","id","lastActive","newId","ONE_YEAR_MS","LocalStorageAdapter","toRemove","readCookies","CookieAdapter","name","cookie","maxAgeSec","secure","eq","MemoryAdapter","createStorage","preferred","TransportError","statusCode","Transport","path","body","controller","timeoutMs","timeoutId","response","blob","ORGANIZATION_ID_KEY","IDENTIFY_SIG_KEY","stableStringify","k","Client","persistedUserId","persistedOrgId","visitor","organization","signature","previousAnonymousId","properties","pagePath","input","organizationId","pageUrl","pageTitle","pageReferrer","setupClient","onGuides","loadBuilder","loadThemeDetector","autocaptureConfig","pending","entry","method","fn","deriveThemeUrl","init","apiUrl","ensureGuides","previewToken","guides","inner","ready"],"mappings":"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","file":"veo.js","sourcesContent":["/**\n * Tipos del contrato HTTP entre el SDK y el backend.\n * Versión 1.\n *\n * IMPORTANTE: Si cambias algo aquí, debes actualizar también:\n * - veo-backend/src/modules/identity/dto/*.dto.ts\n * - veo-backend/src/modules/ingest/dto/*.dto.ts\n * - CONTRACT.md\n */\n\n/** Versión del SDK, inyectada en build desde package.json (tsup `define`); fallback en tests/dev. */\nexport const SDK_VERSION = process.env.VEO_SDK_VERSION ?? '0.0.0-dev';\nexport const MAX_BATCH_SIZE = 100;\nexport const DEFAULT_FLUSH_INTERVAL_MS = 5000;\nexport const DEFAULT_FLUSH_BATCH_SIZE = 20;\n\n/**\n * Backend de Veo, horneado en el bundle. El consumidor NO configura la URL.\n * El valor se inyecta en build-time desde `VEO_API_URL` (ver tsup.config.ts);\n * el literal de aquí es solo el fallback para tests / builds sin esa env.\n * NO es secreta: va al bundle del navegador, igual que la `pk_`.\n */\nexport const DEFAULT_API_URL =\n process.env.VEO_API_URL || 'https://veo-backend-production-8c78.up.railway.app';\n\n/**\n * Tipos de eventos que el SDK envía.\n * Debe coincidir con el CHECK constraint de veo_user_actions.action_type.\n */\nexport type ActionType = 'pageview' | 'track' | 'identify' | 'guide';\n\n/**\n * Payload de un evento individual enviado al endpoint POST /v1/events.\n */\nexport interface ActionPayload {\n actionId: string; // UUID v7 generado en cliente\n endUserId: string;\n organizationId?: string;\n sessionId: string;\n actionType: ActionType;\n actionName?: string;\n occurredAt: string; // ISO 8601\n pageUrl?: string;\n pagePath?: string;\n pageTitle?: string;\n pageReferrer?: string;\n actionProperties?: Record<string, unknown>;\n}\n\n/**\n * Request del endpoint POST /v1/events.\n */\nexport interface IngestEventsRequest {\n events: ActionPayload[]; // máx 100\n}\n\n/**\n * Response del endpoint POST /v1/events.\n */\nexport interface IngestEventsResponse {\n accepted: number;\n deduped: number;\n}\n\n/**\n * Request del endpoint POST /v1/identify.\n */\nexport interface IdentifyRequest {\n endUser: {\n id: string;\n anonymousId?: string;\n traits?: Record<string, unknown>;\n };\n organization?: {\n id: string;\n attributes?: Record<string, unknown>;\n };\n}\n\n/**\n * Response del endpoint POST /v1/identify.\n */\nexport interface IdentifyResponse {\n endUserId: string;\n organizationId: string | null;\n workspaceId: string;\n}\n\n/**\n * Response de error estándar del backend.\n */\nexport interface ErrorResponse {\n error: string;\n details?: unknown;\n statusCode: number;\n}\n","import { DEFAULT_API_URL } from '../contract/v1';\n\n/**\n * Resuelve la URL del backend de Veo. NO es parte de la API pública: el\n * consumidor solo pasa `apiKey` y la URL va quemada en `DEFAULT_API_URL`.\n *\n * Orden de resolución (para desarrollo local / self-host, sin recompilar):\n * 1. `config.apiUrl` si viene (override interno, no tipado en `VeoConfig`).\n * 2. `window.__VEO_API_URL__` si está seteado ANTES de `init()`.\n * 3. `DEFAULT_API_URL` (el backend gestionado).\n */\nexport function resolveApiUrl(config?: unknown): string {\n const fromConfig = (config as { apiUrl?: unknown } | undefined)?.apiUrl;\n if (typeof fromConfig === 'string' && fromConfig.trim()) return fromConfig;\n\n const fromGlobal = (globalThis as { __VEO_API_URL__?: unknown }).__VEO_API_URL__;\n if (typeof fromGlobal === 'string' && fromGlobal.trim()) return fromGlobal;\n\n return DEFAULT_API_URL;\n}\n","/**\n * Helpers para detectar el entorno de ejecución (browser vs SSR/Node) y la\n * disponibilidad de APIs del navegador. El SDK debe poder importarse en Node\n * sin romperse, por eso todo acceso a globals del browser pasa por aquí.\n */\n\n/** ¿Existe el objeto global `window`? */\nexport function hasWindow(): boolean {\n return typeof window !== 'undefined';\n}\n\n/** ¿Existe el objeto global `document`? */\nexport function hasDocument(): boolean {\n return typeof document !== 'undefined';\n}\n\n/** ¿`localStorage` está disponible y es escribible? (puede fallar en modo incógnito) */\nexport function hasLocalStorage(): boolean {\n try {\n if (typeof localStorage === 'undefined') return false;\n const testKey = '__veo_test__';\n localStorage.setItem(testKey, '1');\n localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n}\n\n/** ¿`navigator.sendBeacon` está disponible? */\nexport function hasNavigatorSendBeacon(): boolean {\n return typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function';\n}\n","/**\n * Nombres de los query params del puente builder. Constantes PURAS (sin DOM ni\n * `window`) para poder compartirlas entre el core (browser: `builder-token.ts`)\n * y el helper de servidor `veo-sdk/next` (`src/next.ts`), sin arrastrar código de\n * navegador al bundle de servidor.\n */\n\n/** Token de correlación del handshake. */\nexport const BUILDER_TOKEN_PARAM = 'veoBuilder';\n/** Origen del dashboard de Veo (para postMessage / frame-ancestors). */\nexport const BUILDER_ORIGIN_PARAM = 'veoBuilderOrigin';\n/** `1` → modo \"panel inyectado\": la app es top-level y el editor se inyecta encima. */\nexport const BUILDER_PANEL_PARAM = 'veoBuilderPanel';\n/** Path del panel del editor en el dashboard (default `/guides/design`). */\nexport const BUILDER_PANEL_PATH_PARAM = 'veoBuilderPanelPath';\n/** Id de la guía que se está editando (para cargar/guardar en el panel). */\nexport const BUILDER_GUIDE_PARAM = 'veoGuide';\n","/**\n * Detección del modo PREVIEW POR LINK (`?veoPreview=<token>`). El core solo\n * detecta el param — el canje del token y el render viven en el bundle de\n * guías (`plugins/guides/preview-mode.ts`), que el caller carga\n * (estático en `index.ts`, lazy en `veo.ts`).\n *\n * El nombre del query param es parte del contrato con el dashboard (el link\n * generado por «Previsualizar en mi app»).\n */\nimport { hasWindow } from '../utils/safe-env';\n\nexport const PREVIEW_TOKEN_PARAM = 'veoPreview';\n/**\n * El token se PERSISTE en sessionStorage: al navegar entre páginas de la app la\n * URL pierde `?veoPreview`, y sin esto el modo preview (y su chip de control) se\n * apagaba al saltar de página. sessionStorage sobrevive la navegación de la\n * pestaña y muere al cerrarla — justo el alcance de una sesión de preview.\n */\nconst PREVIEW_TOKEN_KEY = 'veo:preview_token';\n\nfunction session(): Storage | null {\n try {\n return window.sessionStorage;\n } catch {\n return null; // modo privado / sandbox: seguimos solo con la URL\n }\n}\n\n/**\n * Token del link de preview. Lo toma de la URL (`?veoPreview`) y lo persiste; si\n * la URL no lo trae (navegó a otra página), lo recupera de sessionStorage.\n * `null` si no hay ninguno. Se limpia con {@link clearPreviewToken}.\n */\nexport function getPreviewToken(): string | null {\n if (!hasWindow()) return null;\n let fromUrl: string | null = null;\n try {\n const value = new URLSearchParams(window.location.search).get(PREVIEW_TOKEN_PARAM);\n fromUrl = value ? value : null;\n } catch {\n fromUrl = null;\n }\n const store = session();\n if (fromUrl) {\n try {\n store?.setItem(PREVIEW_TOKEN_KEY, fromUrl);\n } catch {\n // no-op: sin storage seguimos con el token de la URL\n }\n return fromUrl;\n }\n try {\n return store?.getItem(PREVIEW_TOKEN_KEY) || null;\n } catch {\n return null;\n }\n}\n\n/** Sale del modo preview: borra el token persistido (lo llama el chip al cerrar). */\nexport function clearPreviewToken(): void {\n try {\n session()?.removeItem(PREVIEW_TOKEN_KEY);\n } catch {\n // no-op\n }\n}\n\n/**\n * `true` cuando la app corre en modo preview-por-link. Igual que en modo\n * builder, el runtime NO debe instalar el plugin de guías: las guías live\n * taparían/duplicarían la guía que se está previsualizando.\n */\nexport function isPreviewMode(): boolean {\n return getPreviewToken() !== null;\n}\n","/**\n * Resolución + persistencia del CONTEXTO de builder.\n *\n * El contexto viaja en la URL (`?veoBuilder=<token>&veoBuilderOrigin=<origen>…`),\n * pero los guards de auth de la app suelen **redirigir y tirar el query string**\n * (p.ej. `/dashboard/home` → `/` para loguearte). Si dependiéramos solo de la URL,\n * el modo builder moriría en ese redirect y nunca podrías diseñar sobre una página\n * detrás de login.\n *\n * Solución (igual que el \"designer mode\" de Pendo): apenas vemos el token en la\n * URL guardamos el contexto en `sessionStorage` y de ahí en más lo leemos como\n * fallback. Así el modo builder **sobrevive a redirects y a un login** dentro de la\n * misma pestaña (incluido el ida-y-vuelta de OAuth). Persiste hasta el teardown o\n * hasta que se cierra la pestaña.\n *\n * Vive en el core (bundle de producción) porque tanto el loader del builder como\n * el gate del runtime de guías necesitan saber si estamos en modo builder. Es\n * mínimo a propósito (ver budget en CLAUDE.md).\n */\nimport { hasWindow } from '../utils/safe-env';\nimport {\n BUILDER_GUIDE_PARAM,\n BUILDER_ORIGIN_PARAM,\n BUILDER_PANEL_PARAM,\n BUILDER_PANEL_PATH_PARAM,\n BUILDER_TOKEN_PARAM,\n} from './builder-constants';\nimport { isPreviewMode } from './preview-loader';\n\n// Re-export para no romper a quien los importa desde aquí (bridge-protocol, etc.).\nexport { BUILDER_ORIGIN_PARAM, BUILDER_TOKEN_PARAM } from './builder-constants';\n\n/** Contexto de la sesión de builder activa en la app. */\nexport interface BuilderClientContext {\n /** Token de correlación del handshake. */\n token: string;\n /** Origen del dashboard de Veo (para postMessage). */\n origin: string | null;\n /** `true` → modo panel inyectado (app top-level, editor encima). */\n panel: boolean;\n /** Id de la guía en edición (para el panel). */\n guide: string | null;\n /** Path del panel del editor en el dashboard (override; default `/guides/design`). */\n panelPath: string | null;\n}\n\nconst CTX_KEY = 'veo:builder_ctx';\n/**\n * Respaldo en localStorage, KEYED POR GUÍA. sessionStorage muere al cerrar la\n * pestaña; para que la sesión del editor \"perdure\" al abrir varias guías o\n * reabrir la misma, además persistimos por guía en localStorage con un TTL.\n * Keyed por guía → dos guías abiertas en pestañas distintas no se pisan.\n */\nconst LS_PREFIX = 'veo:builder_ctx:';\n/**\n * TTL del respaldo. Antes era 12 h y producía \"sesiones fantasma\": cerrabas la\n * pestaña del editor sin teardown y CUALQUIER visita a la app durante 12 h\n * restauraba un contexto viejo (token/plantilla stale) o re-abría el panel.\n * 30 min alcanza para su propósito real — sobrevivir el ida-y-vuelta del login\n * y recuperar un cierre accidental — sin arrastrar sesiones de ayer.\n */\nconst PERSIST_TTL_MS = 30 * 60 * 1000; // 30 min\n\ninterface StoredCtx extends BuilderClientContext {\n savedAt: number;\n}\n\nfunction session(): Storage | null {\n try {\n return window.sessionStorage;\n } catch {\n return null; // sessionStorage puede tirar (modo privado, sandbox)\n }\n}\n\nfunction local(): Storage | null {\n try {\n return window.localStorage;\n } catch {\n return null;\n }\n}\n\nfunction lsKey(guide: string | null): string {\n return LS_PREFIX + (guide || 'default');\n}\n\n/** Persiste el contexto en sessionStorage (pestaña) + localStorage por guía (TTL). */\nfunction persist(ctx: BuilderClientContext): void {\n try {\n session()?.setItem(CTX_KEY, JSON.stringify(ctx));\n } catch {\n // no-op: sin sessionStorage seguimos con el contexto de la URL\n }\n try {\n const stored: StoredCtx = { ...ctx, savedAt: Date.now() };\n local()?.setItem(lsKey(ctx.guide), JSON.stringify(stored));\n } catch {\n // no-op\n }\n}\n\n/** Contexto más reciente no vencido en localStorage (limpia los vencidos de paso). */\nfunction readFreshFromLocal(): BuilderClientContext | null {\n const store = local();\n if (!store) return null;\n let best: StoredCtx | null = null;\n try {\n for (let i = 0; i < store.length; i++) {\n const key = store.key(i);\n if (!key?.startsWith(LS_PREFIX)) continue;\n const raw = store.getItem(key);\n if (!raw) continue;\n let parsed: StoredCtx | null = null;\n try {\n parsed = JSON.parse(raw) as StoredCtx;\n } catch {\n continue;\n }\n if (typeof parsed?.savedAt !== 'number' || Date.now() - parsed.savedAt > PERSIST_TTL_MS) {\n try {\n store.removeItem(key);\n } catch {\n // no-op\n }\n continue;\n }\n if (!best || parsed.savedAt > best.savedAt) best = parsed;\n }\n } catch {\n return null;\n }\n if (!best) return null;\n const { savedAt: _savedAt, ...ctx } = best;\n return ctx;\n}\n\nfunction urlParams(): URLSearchParams | null {\n try {\n const search = new URLSearchParams(window.location.search);\n if (search.get(BUILDER_TOKEN_PARAM)) return search;\n // Fallback: FRAGMENTO (#veoBuilder=…). El dashboard duplica los params en el\n // hash porque, con sesión iniciada en la app, el guard de auth suele\n // redirigir la raíz y el redirect tira el query string — pero los\n // navegadores preservan el fragmento a través de los 3xx. Sin esto, el\n // editor solo abría con el usuario deslogueado.\n const hash = window.location.hash.replace(/^#/, '');\n if (hash.includes(`${BUILDER_TOKEN_PARAM}=`)) return new URLSearchParams(hash);\n return search;\n } catch {\n return null;\n }\n}\n\n/**\n * Contexto de builder activo: el de la URL (que además se persiste) o, si el\n * query string se perdió en un redirect, el guardado en sessionStorage. `null`\n * si no estamos en modo builder.\n */\nexport function resolveBuilderContext(): BuilderClientContext | null {\n if (!hasWindow()) return null;\n const params = urlParams();\n const fromUrl = params?.get(BUILDER_TOKEN_PARAM);\n if (fromUrl) {\n const ctx: BuilderClientContext = {\n token: fromUrl,\n origin: params?.get(BUILDER_ORIGIN_PARAM) ?? null,\n panel: params?.get(BUILDER_PANEL_PARAM) === '1',\n guide: params?.get(BUILDER_GUIDE_PARAM) ?? null,\n panelPath: params?.get(BUILDER_PANEL_PATH_PARAM) ?? null,\n };\n persist(ctx);\n return ctx;\n }\n // Preview-por-link (`?veoPreview`) es un modo EXCLUYENTE del builder: si la app\n // corre en preview NO revivimos una sesión de builder desde la persistencia.\n // Sin esto, abrir un link de preview dentro de los 30 min de haber editado\n // resucitaba el contexto de localStorage y RE-INYECTABA el editor ENCIMA del\n // preview — y ese remonte podía tirar el trabajo sin guardar. Un `?veoBuilder`\n // explícito en la URL sí gana (se resolvió arriba, antes de este chequeo).\n if (isPreviewMode()) return null;\n // Sin token en la URL: primero la pestaña (sessionStorage), y si murió (pestaña\n // nueva / restaurada) caemos al respaldo persistido más reciente y lo\n // re-hidratamos en la sesión para que el resto de la carga sea consistente.\n try {\n const raw = session()?.getItem(CTX_KEY);\n if (raw) return JSON.parse(raw) as BuilderClientContext;\n } catch {\n // sigue al fallback de localStorage\n }\n const fromLocal = readFreshFromLocal();\n if (fromLocal) {\n try {\n session()?.setItem(CTX_KEY, JSON.stringify(fromLocal));\n } catch {\n // no-op\n }\n }\n return fromLocal;\n}\n\n/** Token de builder activo (URL o persistido). */\nexport function resolveBuilderToken(): string | null {\n return resolveBuilderContext()?.token ?? null;\n}\n\n/** Origen del dashboard (URL o persistido). */\nexport function resolveBuilderOrigin(): string | null {\n return resolveBuilderContext()?.origin ?? null;\n}\n\n/** `true` si hay un contexto de builder activo (URL o persistido). */\nexport function isBuilderMode(): boolean {\n return resolveBuilderContext() !== null;\n}\n\n/**\n * Borra el modo builder persistido (al hacer teardown / salir del editor).\n * Limpia la pestaña (sessionStorage) y el respaldo de ESTA guía (localStorage);\n * los respaldos de otras guías siguen (no se pisan al cerrar una).\n */\nexport function clearBuilderToken(): void {\n if (!hasWindow()) return;\n let guide: string | null = null;\n try {\n const raw = session()?.getItem(CTX_KEY);\n if (raw) guide = (JSON.parse(raw) as BuilderClientContext).guide ?? null;\n } catch {\n // no-op\n }\n try {\n session()?.removeItem(CTX_KEY);\n } catch {\n // no-op\n }\n try {\n local()?.removeItem(lsKey(guide));\n } catch {\n // no-op\n }\n}\n","/**\n * Carga perezosa del bundle del builder. El SDK de producción (`veo.js`) es\n * lo único que el cliente integra; cuando el dashboard abre la app con\n * `?veoBuilder=<token>`, este loader inyecta `veo-builder.js` (que se\n * auto-conecta). Así el modo no-code \"simplemente funciona\" sin que el\n * cliente tenga que instalar nada extra.\n *\n * No importa nada del plugin builder para no arrastrar su código al bundle\n * de producción (ver budget en CLAUDE.md). El nombre del query param debe\n * coincidir con `BUILDER_TOKEN_PARAM` de `plugins/builder/bridge-protocol`.\n */\nimport { hasDocument, hasWindow } from '../utils/safe-env';\nimport { resolveBuilderToken } from './builder-token';\n\n/**\n * `true` cuando la app corre en modo builder (URL con `?veoBuilder=<token>`, o\n * el token persistido en sessionStorage tras un redirect de auth). En ese modo\n * el editor pinta las guías vía PREVIEW; el runtime NO debe resolver/renderizar\n * las guías `live` o se duplicarían (la live del runtime + la preview del editor).\n */\nexport { isBuilderMode } from './builder-token';\n\nexport function maybeLoadBuilder(opts: {\n builderUrl?: string;\n debug?: boolean;\n apiKey?: string;\n apiUrl?: string;\n /**\n * Fallback para integraciones por bundler (sin `<script>` de dónde derivar la\n * URL): carga el builder con un `import()` dinámico. Lo pasa SOLO el entry\n * ESM/CJS (`index.ts`), así el bundler lo code-splitea (cero costo en prod, se\n * descarga solo en modo builder). El IIFE NO lo pasa (usa el `<script>`).\n */\n loadBuilder?: () => Promise<unknown>;\n}): void {\n if (!hasWindow() || !hasDocument()) return;\n\n // Lee el token de la URL o de sessionStorage (sobrevive al redirect que tira\n // el query string) y persiste el de la URL apenas lo ve. Sin token → no-op.\n if (resolveBuilderToken() === null) return;\n\n // Dejamos apiKey/apiUrl en un global para que el modo builder VERIFIQUE el\n // token contra el backend (`/v1/builder/verify`) antes de activarse. Solo se\n // setea cuando el builder se carga desde `init()` (integración real); en\n // demos que cargan veo-builder.js a mano no existe → verificación best-effort.\n if (opts.apiKey && opts.apiUrl) {\n (window as unknown as { __veoBuilder?: unknown }).__veoBuilder = {\n apiKey: opts.apiKey,\n apiUrl: opts.apiUrl,\n };\n }\n\n // Ya cargado (el IIFE expone window.veoBuilder).\n if ((window as unknown as { veoBuilder?: unknown }).veoBuilder) return;\n\n const url = opts.builderUrl ?? deriveBuilderUrl();\n if (url) {\n if (document.querySelector(`script[src=\"${url}\"]`)) return;\n const script = document.createElement('script');\n script.src = url;\n script.async = true;\n if (opts.debug) {\n script.addEventListener('error', () => console.error('[veo] no pude cargar', url));\n }\n document.head.appendChild(script);\n return;\n }\n\n // Integración por bundler: no hay `<script>` que derivar. Cargamos el builder\n // con el `import()` dinámico que pasó el entry ESM/CJS. El consumidor NO tiene\n // que copiar `veo-builder.js` ni setear `builderUrl`: \"simplemente funciona\".\n if (opts.loadBuilder) {\n void opts.loadBuilder().catch((err) => {\n if (opts.debug) console.error('[veo] no pude cargar el builder (import dinámico)', err);\n });\n return;\n }\n\n if (opts.debug) {\n console.warn('[veo] builder mode pedido pero no pude resolver la URL de veo-builder.js');\n }\n}\n\n/** Deriva `veo-builder.js` del `<script>` que cargó `veo.js`. */\nfunction deriveBuilderUrl(): string | null {\n const scripts = document.querySelectorAll<HTMLScriptElement>('script[src]');\n for (const script of Array.from(scripts)) {\n if (/\\bveo(\\.min)?\\.js(\\?.*)?$/.test(script.src)) {\n return script.src.replace(/\\bveo(\\.min)?\\.js/, 'veo-builder$1.js');\n }\n }\n return null;\n}\n","/**\n * Carga PEREZOSA del bundle de guías (`veo-guides.js`). El `veo.js` de\n * producción no incluye los renderers ni Floating UI; este loader inyecta el\n * bundle de guías y resuelve con su API (`window.veoGuides`) la primera vez que\n * hace falta (`guides:true` o `veo.preview()`).\n *\n * No importa NADA del plugin guides como valor (solo tipos, que se borran) para\n * no arrastrar su código al bundle principal — igual que `builder-loader`.\n */\nimport type {\n GuidesPluginConfig,\n PreviewGuideInput,\n PreviewHandle,\n PreviewModeHandle,\n PreviewModeOptions,\n} from '../plugins/guides';\nimport type { VeoPlugin } from '../types';\nimport { hasDocument, hasWindow } from '../utils/safe-env';\n\nexport interface VeoGuidesApi {\n guidesPlugin: (config: GuidesPluginConfig) => VeoPlugin;\n previewGuide: (input: PreviewGuideInput) => PreviewHandle;\n closeGuidePreview: () => void;\n runPreviewMode: (opts: PreviewModeOptions) => Promise<PreviewModeHandle | null>;\n}\n\ninterface WindowWithGuides {\n veoGuides?: VeoGuidesApi;\n}\n\nlet cached: Promise<VeoGuidesApi | null> | null = null;\n\n/** Carga (una vez) el bundle de guías y resuelve con su API, o `null` si falla. */\nexport function loadGuides(opts: {\n guidesUrl?: string;\n debug?: boolean;\n}): Promise<VeoGuidesApi | null> {\n cached ??= loadInternal(opts);\n return cached;\n}\n\nfunction loadInternal(opts: { guidesUrl?: string; debug?: boolean }): Promise<VeoGuidesApi | null> {\n return new Promise((resolve) => {\n if (!hasWindow() || !hasDocument()) {\n resolve(null);\n return;\n }\n const win = window as unknown as WindowWithGuides;\n if (win.veoGuides) {\n resolve(win.veoGuides);\n return;\n }\n\n const url = opts.guidesUrl ?? deriveGuidesUrl();\n if (!url) {\n if (opts.debug) console.warn('[veo] no pude resolver la URL de veo-guides.js');\n resolve(null);\n return;\n }\n\n const done = (): void => resolve(win.veoGuides ?? null);\n const existing = document.querySelector<HTMLScriptElement>(`script[src=\"${url}\"]`);\n if (existing) {\n existing.addEventListener('load', done);\n existing.addEventListener('error', () => resolve(null));\n return;\n }\n\n const script = document.createElement('script');\n script.src = url;\n script.async = true;\n script.addEventListener('load', done);\n script.addEventListener('error', () => {\n if (opts.debug) console.error('[veo] no pude cargar', url);\n resolve(null);\n });\n document.head.appendChild(script);\n });\n}\n\n/** Deriva `veo-guides.js` del `<script>` que cargó `veo.js`. */\nfunction deriveGuidesUrl(): string | null {\n const scripts = document.querySelectorAll<HTMLScriptElement>('script[src]');\n for (const script of Array.from(scripts)) {\n if (/\\bveo(\\.min)?\\.js(\\?.*)?$/.test(script.src)) {\n return script.src.replace(/\\bveo(\\.min)?\\.js/, 'veo-guides$1.js');\n }\n }\n return null;\n}\n","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","/** Configuración default de autocaptura. */\nexport const DEFAULT_AUTOCAPTURE_CONFIG = {\n enabled: true,\n captureClicks: true,\n captureSubmits: true,\n captureChanges: true,\n maskAllInputs: true,\n maskAllText: false,\n throttleMs: 100,\n maxTextLength: 200,\n captureElementMetadata: true,\n captureAncestors: 5,\n captureClickQuality: true,\n} as const;\n\n/** Máximo de niveles de ancestros que se permiten capturar. */\nexport const MAX_ANCESTORS = 10;\n\n/** Selectores que SIEMPRE se ignoran (incluso si el cliente no configura blockSelectors). */\nexport const ALWAYS_BLOCK_SELECTORS = [\n '[data-veo-ignore]',\n '.veo-ignore',\n // Inputs sensibles\n 'input[type=\"password\"]',\n 'input[type=\"email\"]',\n 'input[type=\"tel\"]',\n 'input[type=\"hidden\"]',\n // Datos de tarjeta\n '[autocomplete=\"cc-number\"]',\n '[autocomplete=\"cc-csc\"]',\n '[autocomplete=\"cc-exp\"]',\n '[autocomplete=\"cc-name\"]',\n // Otros campos sensibles típicos\n '[name*=\"password\" i]',\n '[name*=\"ssn\" i]',\n '[name*=\"credit\" i]',\n '[name*=\"card\" i]',\n '[id*=\"password\" i]',\n '[id*=\"ssn\" i]',\n];\n\n/** Atributos sensibles que NUNCA se capturan. */\nexport const SENSITIVE_ATTRIBUTES = ['value', 'data-credit-card', 'data-ssn', 'data-password'];\n\n/** Atributos útiles que SIEMPRE se intentan capturar si existen. */\nexport const PRIORITY_ATTRIBUTES = [\n 'id',\n 'name',\n 'type',\n 'role',\n 'href',\n 'data-action',\n 'data-veo-tag',\n 'data-testid',\n 'aria-label',\n 'aria-labelledby',\n];\n\n/** Regex para detectar clases generadas dinámicamente. Se descartan del selector. */\nexport const HASHED_CLASS_PATTERNS = [\n /^css-[a-z0-9]{4,}$/i, // emotion, styled-components nuevas\n /^_[a-z0-9]+_[a-z0-9]{4,}_\\d+$/, // CSS Modules con hash\n /^[a-z]{2,4}-[a-z0-9]{6,}$/i, // Tailwind JIT (a veces)\n /^[a-f0-9]{6,}$/i, // hashes hex puros\n /^sc-[a-z0-9]+$/i, // styled-components legacy\n];\n\n/** Eventos sintéticos/internos que ignoramos. */\nexport const IGNORED_EVENT_PROPERTIES = ['$autocapture', 'pageview'];\n","import { HASHED_CLASS_PATTERNS } from './constants';\n\n/** Determina si una clase parece generada dinámicamente (hash de CSS-in-JS, etc.). */\nexport function isHashedClass(className: string): boolean {\n return HASHED_CLASS_PATTERNS.some((pattern) => pattern.test(className));\n}\n\n/** Filtra las clases de un elemento para quedarse solo con las \"humanas\" (estables). */\nexport function filterHumanClasses(element: Element): string[] {\n return Array.from(element.classList).filter((c) => !isHashedClass(c) && c.length < 64);\n}\n\n/**\n * Atributos estables y semánticos que identifican un elemento mejor que sus\n * clases utilitarias (que cambian con el styling). Orden = prioridad. Producen\n * selectores legibles tipo `button[aria-label=\"Abrir menú\"]` que el usuario\n * puede escribir/reconocer en el editor de segmentos.\n */\nconst STABLE_ATTRIBUTES = [\n 'data-testid',\n 'data-test',\n 'data-cy',\n 'name',\n 'aria-label',\n 'placeholder',\n 'alt',\n 'title',\n // `href` identifica muy bien a los links (`<a>`), un target frecuente de\n // autocapture; va después de los atributos semánticos pero antes de los\n // genéricos. Valores largos (URLs absolutas con query) se descartan por\n // MAX_ATTR_VALUE_LENGTH.\n 'href',\n 'role',\n 'type',\n] as const;\n\n/** Valores de atributo más largos que esto se descartan (no son buenos selectores). */\nconst MAX_ATTR_VALUE_LENGTH = 100;\n\n/** Escape básico de caracteres especiales en CSS (usa CSS.escape si está disponible). */\nfunction cssEscape(value: string): string {\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(value);\n }\n return value.replace(/[!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&');\n}\n\n/**\n * Escape para un valor que va DENTRO de comillas en `[attr=\"...\"]`. A diferencia\n * de `cssEscape`, no escapa espacios ni acentos (las comillas ya los cubren):\n * solo `\\` y `\"`. Así el valor queda igual al texto real y el match por substring\n * del backend funciona con lo que el usuario escribe.\n */\nfunction escapeAttrValue(value: string): string {\n return value.replace(/[\\\\\"]/g, '\\\\$&');\n}\n\n/** Devuelve un selector por atributo estable si el elemento tiene alguno. */\nfunction stableAttributeSelector(element: Element, tag: string): string | null {\n for (const attr of STABLE_ATTRIBUTES) {\n const value = element.getAttribute(attr);\n if (value && value.length > 0 && value.length <= MAX_ATTR_VALUE_LENGTH) {\n return `${tag}[${attr}=\"${escapeAttrValue(value)}\"]`;\n }\n }\n return null;\n}\n\n/** Construye un selector simple y estable para UN elemento. */\nfunction buildElementSelector(element: Element): string {\n const tag = element.tagName.toLowerCase();\n\n // 1. `data-veo-tag`: el nombre semántico que da el cliente. Máxima prioridad.\n const veoTag = element.getAttribute('data-veo-tag');\n if (veoTag) {\n return `${tag}[data-veo-tag=\"${escapeAttrValue(veoTag)}\"]`;\n }\n\n // 2. `id`: único y estable. Lo combinamos con clases humanas (como antes).\n if (element.id) {\n const classes = filterHumanClasses(element);\n const classPart = classes.length > 0 ? `.${classes.map(cssEscape).join('.')}` : '';\n return `${tag}#${cssEscape(element.id)}${classPart}`;\n }\n\n // 3. Atributo estable (aria-label, name, type, role…): más robusto que clases.\n const attrSelector = stableAttributeSelector(element, tag);\n if (attrSelector) return attrSelector;\n\n // 4. Fallback: clases humanas.\n const classes = filterHumanClasses(element);\n const classPart = classes.length > 0 ? `.${classes.map(cssEscape).join('.')}` : '';\n return `${tag}${classPart}`;\n}\n\n/** Construye un selector CSS legible y razonablemente estable para el elemento. */\nexport function buildSelectorPath(element: Element, maxAncestors = 5): string {\n const parts: string[] = [];\n let current: Element | null = element;\n let depth = 0;\n\n while (current && current !== document.documentElement && depth <= maxAncestors) {\n parts.unshift(buildElementSelector(current));\n current = current.parentElement;\n depth++;\n }\n\n return parts.join(' > ');\n}\n","import { hasWindow } from '../../utils/safe-env';\nimport { buildSelectorPath } from './selector-builder';\n\n/**\n * Calidad de los clics (Features → detalle: «Clics de error», «Rage clicks»,\n * «Dead clicks»). Nada se decide mirando el elemento: se observa lo que pasa en\n * la página DESPUÉS del clic durante una ventana corta.\n *\n * - **Dead click:** en `reactionWindowMs` no hubo mutación del DOM, ni cambio\n * de URL, ni petición de red, ni cambio de foco. Cubre botones sin handler,\n * enlaces sin href y handlers que no hacen nada. Una navegación completa\n * (pagehide) cuenta como reacción.\n * - **Rage click:** ≥`rageClicks` clics en `rageWindowMs` (o ≥`rageClicksSlow`\n * en `rageWindowSlowMs`) sobre el mismo elemento. UN evento por ráfaga con\n * `$click_count` y `$reacted_clicks` (cuántos de esos clics sí produjeron\n * reacción: sirve para filtrar contadores/carruseles en el análisis, pero la\n * ráfaga se registra siempre — la frustración es la frecuencia).\n * - **Error click:** en `errorWindowMs` hubo un error JS global, una promesa\n * rechazada sin manejar, un `console.error` o una respuesta de red ≥500.\n *\n * Los tres viajan como `track('$dead_click' | '$rage_click' | '$click_error',\n * payload de autocapture + extras)` por la misma cola, con el mismo\n * `$selector_path`/`$page_path` que los clics: el backend los cuenta con el\n * mismo matching de selectores. Tope `maxPerElement` por elemento y tipo por\n * sesión. Los observadores viven solo durante la ventana.\n */\n\nexport type ClickQualityKind = '$dead_click' | '$rage_click' | '$click_error';\n\nexport interface ClickQualityOptions {\n reactionWindowMs?: number;\n errorWindowMs?: number;\n rageClicks?: number;\n rageWindowMs?: number;\n rageClicksSlow?: number;\n rageWindowSlowMs?: number;\n maxPerElement?: number;\n}\n\nexport type ClickQualityEmit = (\n kind: ClickQualityKind,\n element: Element,\n extra: Record<string, unknown>,\n) => void;\n\ninterface ErrorSignal {\n at: number;\n source: 'error' | 'unhandledrejection' | 'console' | 'fetch' | 'xhr';\n message: string;\n}\n\n/** Observación de un clic: reacción (dead) y errores (error). */\ninterface Observation {\n at: number;\n reacted: boolean;\n}\n\ninterface Burst {\n startedAt: number;\n count: number;\n timer: number;\n}\n\n/** Elementos donde un clic sin reacción visible es normal (escribir, elegir). */\nconst NO_DEAD_TAGS = new Set(['input', 'textarea', 'select', 'option', 'label']);\nconst MAX_ERROR_MESSAGE = 200;\n/** Historial de clics por elemento que se conserva (para la ventana lenta de rage). */\nconst HISTORY_MS = 3000;\n\nconst DEFAULTS: Required<ClickQualityOptions> = {\n reactionWindowMs: 1000,\n errorWindowMs: 2000,\n rageClicks: 3,\n rageWindowMs: 1000,\n rageClicksSlow: 5,\n rageWindowSlowMs: 3000,\n maxPerElement: 50,\n};\n\nfunction describeError(value: unknown): string {\n let text: string;\n if (value instanceof Error) text = `${value.name}: ${value.message}`;\n else if (typeof value === 'string') text = value;\n else {\n try {\n text = JSON.stringify(value) ?? String(value);\n } catch {\n text = String(value);\n }\n }\n return text.slice(0, MAX_ERROR_MESSAGE);\n}\n\nexport class ClickQualityTracker {\n private readonly opts: Required<ClickQualityOptions>;\n private installed = false;\n private cleanups: Array<() => void> = [];\n\n // Sensores globales (contadores: cada observación compara su foto inicial).\n private netCount = 0;\n private navCount = 0;\n private focusCount = 0;\n private unloading = false;\n private errors: ErrorSignal[] = [];\n\n private readonly history = new Map<Element, Observation[]>();\n private readonly bursts = new Map<Element, Burst>();\n private readonly emitted = new Map<string, Record<ClickQualityKind, number>>();\n\n constructor(\n private readonly emit: ClickQualityEmit,\n options: ClickQualityOptions = {},\n ) {\n this.opts = { ...DEFAULTS, ...options };\n }\n\n install(): void {\n if (this.installed || !hasWindow()) return;\n this.installed = true;\n\n const on = <K extends keyof WindowEventMap>(\n type: K,\n handler: (e: WindowEventMap[K]) => void,\n capture = true,\n ): void => {\n window.addEventListener(type, handler, capture);\n this.cleanups.push(() => window.removeEventListener(type, handler, capture));\n };\n\n on('error', (e) => {\n const err = e as ErrorEvent;\n this.pushError('error', err.error ?? err.message ?? 'error');\n });\n on('unhandledrejection', (e) => {\n this.pushError('unhandledrejection', (e as PromiseRejectionEvent).reason ?? 'rejection');\n });\n on('popstate', () => this.navCount++);\n on('hashchange', () => this.navCount++);\n on('focusin', () => this.focusCount++);\n on('pagehide', () => {\n this.unloading = true;\n });\n on('beforeunload', () => {\n this.unloading = true;\n });\n\n this.patchHistory();\n this.patchConsole();\n this.patchFetch();\n this.patchXhr();\n }\n\n destroy(): void {\n for (const c of this.cleanups) c();\n this.cleanups = [];\n for (const b of this.bursts.values()) window.clearTimeout(b.timer);\n this.bursts.clear();\n this.history.clear();\n this.installed = false;\n }\n\n /** Llamar por cada clic real sobre un elemento interactivo, ANTES del throttle. */\n onClick(element: Element, event?: Partial<MouseEvent>): void {\n if (!this.installed) return;\n const now = Date.now();\n const obs: Observation = { at: now, reacted: false };\n this.remember(element, obs);\n this.observeReaction(element, obs, event);\n this.observeErrors(element, now);\n this.trackRage(element, now);\n }\n\n // ---------------------------------------------------------------- dead ----\n\n private observeReaction(element: Element, obs: Observation, event?: Partial<MouseEvent>): void {\n const netAtClick = this.netCount;\n const navAtClick = this.navCount;\n const focusAtClick = this.focusCount;\n const hrefAtClick = window.location.href;\n const skipDead = this.isDeadExempt(element, event);\n\n let observer: MutationObserver | null = null;\n if (typeof MutationObserver !== 'undefined') {\n observer = new MutationObserver(() => {\n obs.reacted = true;\n observer?.disconnect();\n observer = null;\n });\n observer.observe(document.documentElement, {\n childList: true,\n attributes: true,\n characterData: true,\n subtree: true,\n });\n }\n window.setTimeout(() => {\n observer?.disconnect();\n const reacted =\n obs.reacted ||\n this.unloading ||\n this.netCount !== netAtClick ||\n this.navCount !== navAtClick ||\n this.focusCount !== focusAtClick ||\n window.location.href !== hrefAtClick;\n obs.reacted = reacted;\n if (!reacted && !skipDead) this.report('$dead_click', element, {});\n }, this.opts.reactionWindowMs);\n }\n\n private isDeadExempt(element: Element, event?: Partial<MouseEvent>): boolean {\n if (event && (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey)) return true;\n if (event && typeof event.button === 'number' && event.button !== 0) return true;\n const tag = element.tagName.toLowerCase();\n if (NO_DEAD_TAGS.has(tag)) return true;\n if (element.closest('[contenteditable=\"\"],[contenteditable=\"true\"]')) return true;\n const anchor = element.closest('a');\n if (anchor) {\n if (anchor.target === '_blank' || anchor.hasAttribute('download')) return true;\n const href = anchor.getAttribute('href') ?? '';\n if (/^(mailto|tel|sms):/i.test(href)) return true;\n }\n return false;\n }\n\n // --------------------------------------------------------------- error ----\n\n private observeErrors(element: Element, clickedAt: number): void {\n const deadline = clickedAt + this.opts.errorWindowMs;\n // Poll liviano: los errores llegan por listeners globales; acá solo se\n // asocia el primero posterior al clic dentro de la ventana.\n const check = (): void => {\n const err = this.errors.find((e) => e.at >= clickedAt && e.at <= deadline);\n if (err) {\n this.report('$click_error', element, {\n $error_source: err.source,\n $error_message: err.message,\n });\n return;\n }\n if (Date.now() < deadline) window.setTimeout(check, 250);\n };\n window.setTimeout(check, 250);\n }\n\n private pushError(source: ErrorSignal['source'], value: unknown): void {\n const message = describeError(value);\n if (message.startsWith('[veo]')) return; // logs propios del SDK\n this.errors.push({ at: Date.now(), source, message });\n // Mantener solo lo reciente: los observadores miran hacia atrás como mucho errorWindowMs.\n const cutoff = Date.now() - this.opts.errorWindowMs - 1000;\n while (this.errors.length > 0 && (this.errors[0] as ErrorSignal).at < cutoff) {\n this.errors.shift();\n }\n if (this.errors.length > 50) this.errors.splice(0, this.errors.length - 50);\n }\n\n // ---------------------------------------------------------------- rage ----\n\n private remember(element: Element, obs: Observation): void {\n const list = this.history.get(element) ?? [];\n const cutoff = obs.at - HISTORY_MS;\n const kept = list.filter((o) => o.at >= cutoff);\n kept.push(obs);\n this.history.set(element, kept);\n // No acumular elementos que ya no se clickean.\n if (this.history.size > 100) {\n for (const [el, obsList] of this.history) {\n if (obsList.every((o) => o.at < cutoff)) this.history.delete(el);\n }\n }\n }\n\n private trackRage(element: Element, now: number): void {\n const list = this.history.get(element) ?? [];\n const fast = list.filter((o) => o.at >= now - this.opts.rageWindowMs).length;\n const slow = list.filter((o) => o.at >= now - this.opts.rageWindowSlowMs).length;\n const existing = this.bursts.get(element);\n const isRage = fast >= this.opts.rageClicks || slow >= this.opts.rageClicksSlow;\n if (!existing && !isRage) return;\n\n const burst: Burst = existing ?? {\n startedAt: (list.find((o) => o.at >= now - this.opts.rageWindowSlowMs) ?? { at: now }).at,\n count: 0,\n timer: 0,\n };\n burst.count = list.filter((o) => o.at >= burst.startedAt).length;\n window.clearTimeout(burst.timer);\n // La ráfaga termina cuando pasa la ventana de reacción del último clic sin\n // clics nuevos: ahí ya se sabe si los clics reaccionaron.\n burst.timer = window.setTimeout(() => {\n this.bursts.delete(element);\n const clicks = (this.history.get(element) ?? []).filter((o) => o.at >= burst.startedAt);\n this.report('$rage_click', element, {\n $click_count: Math.max(clicks.length, burst.count),\n $reacted_clicks: clicks.filter((o) => o.reacted).length,\n });\n }, this.opts.reactionWindowMs + 50);\n this.bursts.set(element, burst);\n }\n\n // ---------------------------------------------------------------- emit ----\n\n private report(kind: ClickQualityKind, element: Element, extra: Record<string, unknown>): void {\n const key = buildSelectorPath(element, 5);\n const counts = this.emitted.get(key) ?? { $dead_click: 0, $rage_click: 0, $click_error: 0 };\n if (counts[kind] >= this.opts.maxPerElement) return;\n counts[kind]++;\n this.emitted.set(key, counts);\n try {\n this.emit(kind, element, extra);\n } catch {\n // nunca romper la app del cliente\n }\n }\n\n // ------------------------------------------------------------- patches ----\n\n private patchHistory(): void {\n const h = window.history;\n if (!h) return;\n const origPush = h.pushState;\n const origReplace = h.replaceState;\n const self = this;\n h.pushState = function (this: History, ...args: Parameters<History['pushState']>) {\n self.navCount++;\n return origPush.apply(this, args);\n };\n h.replaceState = function (this: History, ...args: Parameters<History['replaceState']>) {\n self.navCount++;\n return origReplace.apply(this, args);\n };\n this.cleanups.push(() => {\n h.pushState = origPush;\n h.replaceState = origReplace;\n });\n }\n\n private patchConsole(): void {\n const orig = console.error;\n const self = this;\n console.error = function (this: Console, ...args: unknown[]) {\n try {\n self.pushError('console', args.map(describeError).join(' '));\n } catch {\n // no-op\n }\n return orig.apply(this, args);\n };\n this.cleanups.push(() => {\n console.error = orig;\n });\n }\n\n /**\n * `fetch`: cuenta la petición (reacción) y registra respuestas ≥500 o\n * rechazos como error. Se observa con `.then(ok, err)` sobre la promesa\n * original: eso marca el rechazo como manejado para el navegador, así que\n * un fetch fallido sin catch de la app no dispara `unhandledrejection` —\n * lo registramos nosotros como error de red.\n */\n private patchFetch(): void {\n if (typeof window.fetch !== 'function') return;\n const orig = window.fetch;\n const self = this;\n window.fetch = function (this: unknown, ...args: Parameters<typeof fetch>) {\n self.netCount++;\n const p = orig.apply(this, args);\n if (p && typeof p.then === 'function') {\n p.then(\n (res) => {\n if (res && res.status >= 500) self.pushError('fetch', `${res.status} ${res.url}`);\n },\n (err) => self.pushError('fetch', err),\n );\n }\n return p;\n };\n this.cleanups.push(() => {\n window.fetch = orig;\n });\n }\n\n private patchXhr(): void {\n const proto = typeof XMLHttpRequest !== 'undefined' ? XMLHttpRequest.prototype : null;\n if (!proto) return;\n const origSend = proto.send;\n const self = this;\n proto.send = function (this: XMLHttpRequest, ...args: Parameters<XMLHttpRequest['send']>) {\n self.netCount++;\n try {\n this.addEventListener('loadend', () => {\n if (this.status >= 500) self.pushError('xhr', `${this.status} ${this.responseURL}`);\n });\n } catch {\n // no-op\n }\n return origSend.apply(this, args);\n };\n this.cleanups.push(() => {\n proto.send = origSend;\n });\n }\n}\n","import { ALWAYS_BLOCK_SELECTORS, SENSITIVE_ATTRIBUTES } from './constants';\n\n/**\n * Verifica si un elemento o ALGUNO de sus ancestros está en la blacklist.\n * Recorre hacia arriba para que bloquear un contenedor bloquee su subárbol.\n */\nexport function isElementBlocked(element: Element, extraBlockSelectors: string[] = []): boolean {\n const allBlockers = [...ALWAYS_BLOCK_SELECTORS, ...extraBlockSelectors];\n let current: Element | null = element;\n\n while (current && current !== document.documentElement) {\n for (const selector of allBlockers) {\n try {\n if (current.matches(selector)) return true;\n } catch {\n // Selector inválido o no soportado por el motor: ignorar y seguir.\n }\n }\n current = current.parentElement;\n }\n\n return false;\n}\n\n/** Verifica si un atributo es sensible y debe omitirse. */\nexport function isSensitiveAttribute(attrName: string): boolean {\n const lower = attrName.toLowerCase();\n return SENSITIVE_ATTRIBUTES.includes(lower) || /password|secret|token|ssn|credit/i.test(attrName);\n}\n\n/** Obtiene el texto visible de un elemento, respetando privacidad. */\nexport function safeGetText(element: Element, maxLength: number, mask: boolean): string {\n if (mask) return '';\n\n // Nunca capturar texto de campos de entrada (puede contener lo que el usuario escribe).\n const tagName = element.tagName.toLowerCase();\n if (tagName === 'input' || tagName === 'textarea') return '';\n\n // `innerText` no existe en jsdom; el fallback a `textContent` lo cubre.\n const raw =\n (element instanceof HTMLElement ? element.innerText : '') || element.textContent || '';\n const trimmed = raw.trim().replace(/\\s+/g, ' ');\n\n return trimmed.length > maxLength ? `${trimmed.slice(0, maxLength)}…` : trimmed;\n}\n","import { PRIORITY_ATTRIBUTES } from './constants';\nimport { isSensitiveAttribute, safeGetText } from './pii-guard';\nimport { buildSelectorPath, filterHumanClasses } from './selector-builder';\n\nexport interface SerializedElement {\n tag: string;\n id: string | null;\n classes: string[];\n text: string;\n attributes: Record<string, string>;\n position: { x: number; y: number; w: number; h: number };\n}\n\nexport interface SerializedAncestor {\n tag: string;\n id: string | null;\n classes: string[];\n veoTag: string | null;\n}\n\nexport interface AutocapturePayload {\n $event_type: 'click' | 'submit' | 'change';\n $element: SerializedElement;\n $ancestors: SerializedAncestor[];\n $selector_path: string;\n $page_url: string;\n $page_path: string;\n}\n\ninterface SerializeConfig {\n maxTextLength: number;\n maskAllText: boolean;\n captureElementMetadata: boolean;\n}\n\n/** Extrae los atributos relevantes del elemento, filtrando los sensibles. */\nfunction extractPriorityAttributes(element: Element): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const attrName of PRIORITY_ATTRIBUTES) {\n const value = element.getAttribute(attrName);\n if (value !== null && !isSensitiveAttribute(attrName) && value.length < 256) {\n result[attrName] = value;\n }\n }\n\n return result;\n}\n\n/** Serializa un elemento DOM a un objeto plano para enviar al backend. */\nexport function serializeElement(element: Element, config: SerializeConfig): SerializedElement {\n const rect = element.getBoundingClientRect();\n\n return {\n tag: element.tagName.toLowerCase(),\n id: element.id || null,\n classes: filterHumanClasses(element),\n text: safeGetText(element, config.maxTextLength, config.maskAllText),\n attributes: config.captureElementMetadata ? extractPriorityAttributes(element) : {},\n position: {\n x: Math.round(rect.left + window.scrollX),\n y: Math.round(rect.top + window.scrollY),\n w: Math.round(rect.width),\n h: Math.round(rect.height),\n },\n };\n}\n\n/** Captura los ancestros del elemento (para tagging contextual en el dashboard). */\nexport function serializeAncestors(element: Element, maxDepth: number): SerializedAncestor[] {\n const ancestors: SerializedAncestor[] = [];\n let current: Element | null = element.parentElement;\n let depth = 0;\n\n while (current && current !== document.documentElement && depth < maxDepth) {\n ancestors.push({\n tag: current.tagName.toLowerCase(),\n id: current.id || null,\n classes: filterHumanClasses(current),\n veoTag: current.getAttribute('data-veo-tag') || null,\n });\n current = current.parentElement;\n depth++;\n }\n\n return ancestors;\n}\n\n/** Construye el payload completo para el evento `$autocapture`. */\nexport function buildAutocapturePayload(\n eventType: 'click' | 'submit' | 'change',\n element: Element,\n config: SerializeConfig & { captureAncestors: number },\n): AutocapturePayload {\n return {\n $event_type: eventType,\n $element: serializeElement(element, config),\n $ancestors: serializeAncestors(element, config.captureAncestors),\n $selector_path: buildSelectorPath(element, config.captureAncestors),\n $page_url: window.location.href,\n $page_path: window.location.pathname,\n };\n}\n","/**\n * Throttle por elemento: evita duplicar eventos del mismo target dentro de una\n * ventana de N ms. Usa un WeakMap para no retener elementos en memoria.\n */\nexport class ElementThrottle {\n private lastFired = new WeakMap<Element, number>();\n\n constructor(private readonly windowMs: number) {}\n\n /** Devuelve true si el elemento puede emitir ahora (y registra el disparo). */\n shouldFire(element: Element): boolean {\n const now = Date.now();\n const last = this.lastFired.get(element) ?? 0;\n\n if (now - last < this.windowMs) return false;\n\n this.lastFired.set(element, now);\n return true;\n }\n}\n","import type { VeoAutocaptureConfig, VeoClient } from '../../types';\nimport { hasDocument } from '../../utils/safe-env';\nimport { ClickQualityTracker } from './click-quality';\nimport { DEFAULT_AUTOCAPTURE_CONFIG, MAX_ANCESTORS } from './constants';\nimport { buildAutocapturePayload } from './element-serializer';\nimport { isElementBlocked } from './pii-guard';\nimport { ElementThrottle } from './throttle';\n\ntype AutocaptureEvent = 'click' | 'submit' | 'change';\n\n/**\n * Instala listeners delegados en `document` y traduce las interacciones del\n * usuario en eventos `$autocapture`. Nunca lanza hacia la app del cliente:\n * cada handler está envuelto en try/catch.\n */\nexport class DomListener {\n private readonly throttle: ElementThrottle;\n private readonly config: Required<VeoAutocaptureConfig>;\n private cleanups: Array<() => void> = [];\n private quality: ClickQualityTracker | null = null;\n\n constructor(\n private readonly client: VeoClient,\n config: VeoAutocaptureConfig,\n ) {\n const d = DEFAULT_AUTOCAPTURE_CONFIG;\n // Resolver el config de forma explícita: el merge por spread reintroduce\n // `| undefined` y no satisface `Required<VeoAutocaptureConfig>`.\n this.config = {\n enabled: config.enabled ?? d.enabled,\n captureClicks: config.captureClicks ?? d.captureClicks,\n captureSubmits: config.captureSubmits ?? d.captureSubmits,\n captureChanges: config.captureChanges ?? d.captureChanges,\n maskAllInputs: config.maskAllInputs ?? d.maskAllInputs,\n maskAllText: config.maskAllText ?? d.maskAllText,\n blockSelectors: config.blockSelectors ?? [],\n throttleMs: config.throttleMs ?? d.throttleMs,\n maxTextLength: config.maxTextLength ?? d.maxTextLength,\n captureElementMetadata: config.captureElementMetadata ?? d.captureElementMetadata,\n captureAncestors: Math.min(config.captureAncestors ?? d.captureAncestors, MAX_ANCESTORS),\n captureClickQuality: config.captureClickQuality ?? d.captureClickQuality,\n };\n this.throttle = new ElementThrottle(this.config.throttleMs);\n }\n\n install(): void {\n if (!hasDocument() || !this.config.enabled) return;\n\n if (this.config.captureClicks && this.config.captureClickQuality) {\n // Dead / rage / error clicks: mismo payload que el clic + extras.\n this.quality = new ClickQualityTracker((kind, element, extra) => {\n const payload = buildAutocapturePayload('click', element, this.config);\n this.client.track(kind, { ...payload, ...extra } as unknown as Record<string, unknown>);\n });\n this.quality.install();\n }\n if (this.config.captureClicks) this.attach('click', (e) => this.handleClick(e));\n if (this.config.captureSubmits) this.attach('submit', (e) => this.handleSubmit(e), true);\n if (this.config.captureChanges) this.attach('change', (e) => this.handleChange(e), true);\n }\n\n destroy(): void {\n for (const cleanup of this.cleanups) cleanup();\n this.cleanups = [];\n this.quality?.destroy();\n this.quality = null;\n }\n\n private attach(\n eventName: AutocaptureEvent,\n handler: (e: Event) => void,\n useCapture = false,\n ): void {\n const listener = (e: Event) => {\n // Solo eventos reales del usuario (los sintéticos tienen isTrusted=false).\n if (!e.isTrusted) return;\n try {\n handler(e);\n } catch {\n // Nunca romper la app del cliente; descartamos el evento silenciosamente.\n }\n };\n document.addEventListener(eventName, listener, useCapture);\n this.cleanups.push(() => document.removeEventListener(eventName, listener, useCapture));\n }\n\n private handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n // Subir hasta el elemento \"interesante\" (botón, link, [role], etc.).\n // Si NO hay ninguno (click en zona vacía/no interactiva, p. ej. <html>),\n // no emitimos: evita ruido y volumen innecesario de eventos.\n const meaningful = this.findMeaningfulAncestor(target);\n if (!meaningful) return;\n if (isElementBlocked(meaningful, this.config.blockSelectors)) return;\n // Calidad del clic ANTES del throttle: una ráfaga (rage) son clics repetidos.\n this.quality?.onClick(meaningful, event as MouseEvent);\n if (!this.throttle.shouldFire(meaningful)) return;\n\n this.emit('click', meaningful);\n }\n\n private handleSubmit(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element) || target.tagName.toLowerCase() !== 'form') return;\n if (isElementBlocked(target, this.config.blockSelectors)) return;\n if (!this.throttle.shouldFire(target)) return;\n\n this.emit('submit', target);\n }\n\n private handleChange(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const tag = target.tagName.toLowerCase();\n if (tag !== 'select' && tag !== 'input' && tag !== 'textarea') return;\n\n // Para text inputs el change sería spam/PII; solo checkbox/radio (y selects).\n if (\n target instanceof HTMLInputElement &&\n target.type !== 'checkbox' &&\n target.type !== 'radio'\n ) {\n return;\n }\n if (isElementBlocked(target, this.config.blockSelectors)) return;\n if (!this.throttle.shouldFire(target)) return;\n\n this.emit('change', target);\n }\n\n /** Busca hacia arriba un ancestro \"interactivo\". Devuelve null si no hay ninguno. */\n private findMeaningfulAncestor(element: Element): Element | null {\n let current: Element | null = element;\n let depth = 0;\n\n while (current && current !== document.documentElement && depth < 5) {\n const tag = current.tagName.toLowerCase();\n const isInteractive =\n tag === 'button' ||\n tag === 'a' ||\n tag === 'input' ||\n tag === 'select' ||\n tag === 'textarea' ||\n current.hasAttribute('data-veo-tag') ||\n current.hasAttribute('role') ||\n current.hasAttribute('onclick') ||\n (current instanceof HTMLElement && current.style.cursor === 'pointer');\n\n if (isInteractive) return current;\n current = current.parentElement;\n depth++;\n }\n\n return null;\n }\n\n private emit(eventType: AutocaptureEvent, element: Element): void {\n const payload = buildAutocapturePayload(eventType, element, this.config);\n this.client.track('$autocapture', payload as unknown as Record<string, unknown>);\n }\n}\n","import type { VeoAutocaptureConfig, VeoPlugin } from '../../types';\nimport { definePlugin } from '../plugin';\nimport { DomListener } from './dom-listener';\n\n/**\n * Plugin de autocaptura de eventos del DOM.\n * Captura clicks, submits y changes automáticamente y los emite como\n * eventos `track('$autocapture', …)` por la Queue del cliente.\n */\nexport function autocapturePlugin(config: VeoAutocaptureConfig = {}): VeoPlugin {\n let listener: DomListener | null = null;\n\n return definePlugin({\n name: 'autocapture',\n install(client) {\n listener = new DomListener(client, config);\n listener.install();\n },\n destroy() {\n listener?.destroy();\n listener = null;\n },\n });\n}\n\nexport { DomListener } from './dom-listener';\nexport type { AutocapturePayload } from './element-serializer';\n","import type { VeoPlugin } from '../types';\nimport { hasWindow } from '../utils/safe-env';\nimport { definePlugin } from './plugin';\n\n/**\n * Plugin que auto-emite `pageview` en cambios de ruta de una SPA.\n * Cubre `history.pushState`, `history.replaceState`, `popstate` y `hashchange`.\n */\nexport function spaRouterPlugin(): VeoPlugin {\n return definePlugin({\n name: 'spa-router',\n install(client) {\n if (!hasWindow()) return;\n\n // Pageview inicial.\n client.pageview();\n\n const fire = () => {\n // Diferir para que el router del host actualice location.pathname primero.\n queueMicrotask(() => client.pageview());\n };\n\n const origPushState = window.history.pushState;\n const origReplaceState = window.history.replaceState;\n\n window.history.pushState = function (\n this: History,\n ...args: Parameters<History['pushState']>\n ): void {\n origPushState.apply(this, args);\n fire();\n };\n\n window.history.replaceState = function (\n this: History,\n ...args: Parameters<History['replaceState']>\n ): void {\n origReplaceState.apply(this, args);\n fire();\n };\n\n window.addEventListener('popstate', fire);\n window.addEventListener('hashchange', fire);\n },\n });\n}\n","import type { VeoPlugin } from '../../types';\nimport { hasDocument, hasWindow } from '../../utils/safe-env';\nimport type { ThemeMode, ThemeSnapshot } from './types';\n\nexport type {\n DetectedColor,\n DetectedFont,\n DetectedPalette,\n ThemeColorRole,\n ThemeMode,\n ThemeSnapshot,\n} from './types';\n\n/**\n * El detector (pesado: muestreo del DOM, hojas de estilo, fuentes) vive en\n * `detect-theme.ts` y llega por carga perezosa; este archivo es solo el\n * planificador liviano que va en el core. NO importar `detect-theme` acá.\n */\nexport interface ThemeDetectorApi {\n detectTheme: (doc?: Document) => ThemeSnapshot | null;\n snapshotHash: (snapshot: ThemeSnapshot) => string;\n}\n\nexport interface ThemeDetectPluginConfig {\n apiUrl: string;\n apiKey: string;\n debug?: boolean;\n /** Trae el detector: `import()` dinámico (bundlers) o `<script>` (IIFE). */\n loadDetector: () => Promise<ThemeDetectorApi | null>;\n}\n\nconst STORAGE_PREFIX = 'veo_theme_';\n/** Como mucho un envío al día por navegador y por modo de color. */\nconst RESEND_AFTER_MS = 24 * 60 * 60 * 1000;\n/** Espera tras el `load`: la app termina de hidratar y pintar su UI real. */\nconst SETTLE_MS = 4000;\n/** Tope de detecciones por carga de página (una app puede tocar `<html class>` seguido). */\nconst MAX_RUNS_PER_PAGE = 4;\n\ninterface SentRecord {\n hash: string;\n at: number;\n}\nexport type SentState = Partial<Record<ThemeMode, SentRecord>>;\n\nfunction readState(key: string): SentState {\n try {\n const raw = localStorage.getItem(key);\n const parsed: unknown = raw ? JSON.parse(raw) : null;\n return parsed && typeof parsed === 'object' ? (parsed as SentState) : {};\n } catch {\n return {};\n }\n}\n\nfunction writeState(key: string, state: SentState): void {\n try {\n localStorage.setItem(key, JSON.stringify(state));\n } catch {\n // Sin storage (incógnito, cuota): se reintenta en la próxima carga.\n }\n}\n\n/**\n * Modo de color APARENTE, barato (sin tocar estilos): decide si vale la pena\n * descargar el detector. El modo real lo determina `detectTheme`.\n */\nexport function guessMode(doc: Document, prefersDark: boolean): ThemeMode {\n const hints = [\n doc.documentElement.className,\n doc.documentElement.dataset.theme,\n doc.documentElement.dataset.mode,\n doc.body?.className,\n ]\n .join(' ')\n .toLowerCase();\n if (/\\bdark\\b/.test(hints)) return 'dark';\n if (/\\blight\\b/.test(hints)) return 'light';\n return prefersDark ? 'dark' : 'light';\n}\n\n/** ¿Este modo ya se reportó hace menos de un día? Entonces ni se carga el detector. */\nexport function isFresh(state: SentState, mode: ThemeMode, now: number): boolean {\n const last = state[mode];\n return last !== undefined && now - last.at < RESEND_AFTER_MS;\n}\n\n/** ¿Hay que enviar? No, si es igual al último envío de ese modo y aún no pasó un día. */\nexport function shouldSendSnapshot(\n state: SentState,\n mode: ThemeMode,\n hash: string,\n now: number,\n): boolean {\n const last = state[mode];\n return !last || last.hash !== hash || now - last.at >= RESEND_AFTER_MS;\n}\n\n/**\n * Detecta el tema de la app (colores por modo + fuentes) y lo reporta al\n * backend para que el design system de OnUser arranque ya con la marca del\n * cliente. Corre en idle, después del `load`, y como mucho una vez al día por\n * navegador y modo; también cuando el usuario alterna claro/oscuro. Solo viajan\n * colores y nombres de fuentes. Best-effort: cualquier fallo se ignora.\n */\nexport function themeDetectPlugin(config: ThemeDetectPluginConfig): VeoPlugin {\n const storageKey = `${STORAGE_PREFIX}${config.apiKey.slice(-16) || 'default'}`;\n let observer: MutationObserver | null = null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let destroyed = false;\n let runs = 0;\n\n const run = async (): Promise<void> => {\n if (destroyed || runs >= MAX_RUNS_PER_PAGE) return;\n const prefersDark =\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-color-scheme: dark)').matches;\n const guess = guessMode(document, prefersDark);\n if (isFresh(readState(storageKey), guess, Date.now())) return;\n runs++;\n try {\n const detector = await config.loadDetector();\n if (!detector || destroyed) return;\n const snapshot = detector.detectTheme();\n if (!snapshot) return;\n const hash = detector.snapshotHash(snapshot);\n const state = readState(storageKey);\n const now = Date.now();\n const mark = (): void => {\n const record = { hash, at: Date.now() };\n state[snapshot.mode] = record;\n // Si el modo aparente no coincide con el real (la app ignora\n // prefers-color-scheme), se marca también: evita re-detectar en cada carga.\n state[guess] = state[guess] && guess !== snapshot.mode ? state[guess] : record;\n writeState(storageKey, state);\n };\n if (!shouldSendSnapshot(state, snapshot.mode, hash, now)) {\n mark();\n return;\n }\n if (config.debug) console.log('[veo] theme snapshot', snapshot);\n const res = await fetch(`${config.apiUrl}/v1/workspaces/theme-snapshot`, {\n method: 'POST',\n headers: { 'X-Api-Key': config.apiKey, 'Content-Type': 'application/json' },\n body: JSON.stringify(snapshot),\n credentials: 'omit',\n });\n if (res.ok) mark();\n } catch (err) {\n if (config.debug) console.warn('[veo] theme detect failed', err);\n }\n };\n\n const schedule = (delayMs: number): void => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n const idle = (window as unknown as { requestIdleCallback?: (cb: () => void) => void })\n .requestIdleCallback;\n if (typeof idle === 'function') idle(() => void run());\n else void run();\n }, delayMs);\n };\n\n return {\n name: 'theme-detect',\n install() {\n if (!hasWindow() || !hasDocument()) return;\n if (document.readyState === 'complete') schedule(SETTLE_MS);\n else window.addEventListener('load', () => schedule(SETTLE_MS), { once: true });\n // El usuario alternó claro/oscuro: se detecta el nuevo modo en vivo.\n if (typeof MutationObserver === 'function') {\n observer = new MutationObserver(() => schedule(1500));\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class', 'data-theme', 'data-mode'],\n });\n }\n },\n destroy() {\n destroyed = true;\n observer?.disconnect();\n if (timer) clearTimeout(timer);\n },\n };\n}\n","/**\n * Genera un UUID v7 (timestamp-based, ordenable cronológicamente).\n * Spec: RFC 9562.\n *\n * Formato: tttttttt-tttt-7xxx-yxxx-xxxxxxxxxxxx\n * - 48 bits de timestamp (ms desde epoch)\n * - 4 bits de versión (7)\n * - 2 bits de variante (10)\n * - 74 bits aleatorios\n */\nexport function uuidv7(): string {\n const timestamp = Date.now();\n const timeHex = timestamp.toString(16).padStart(12, '0');\n\n // 10 bytes aleatorios para los 74 bits de entropía (+ bits de versión/variante).\n const random = new Uint8Array(10);\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n crypto.getRandomValues(random);\n } else {\n // Fallback inseguro pero funcional (no debería ocurrir en browsers modernos).\n for (let i = 0; i < random.length; i++) {\n random[i] = Math.floor(Math.random() * 256);\n }\n }\n\n // Set version (7) en el primer nibble del 3er grupo.\n random[0] = ((random[0] ?? 0) & 0x0f) | 0x70;\n // Set variant (10) en los 2 bits altos del 4to grupo.\n random[2] = ((random[2] ?? 0) & 0x3f) | 0x80;\n\n const hex = Array.from(random, (b) => b.toString(16).padStart(2, '0')).join('');\n\n return [\n timeHex.slice(0, 8),\n timeHex.slice(8, 12),\n hex.slice(0, 4),\n hex.slice(4, 8),\n hex.slice(8, 20),\n ].join('-');\n}\n","import type { Transport } from './transport';\n\nexport interface QueueConfig {\n transport: Transport;\n flushIntervalMs: number;\n batchSize: number;\n maxRetries?: number;\n onError?: (error: Error) => void;\n}\n\nconst RETRY_MAX_DELAY_MS = 30000;\n\n/**\n * Buffer de eventos con envío en batch, flush por intervalo o por tamaño, y\n * reintentos con backoff exponencial ante fallos de red. Los eventos que fallan\n * se re-encolan al inicio para preservar el orden.\n */\nexport class Queue<T = unknown> {\n private buffer: T[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n private retryCount = 0;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private readonly config: QueueConfig) {\n this.startTimer();\n }\n\n /** Encola un evento; dispara flush si se alcanza `batchSize`. */\n add(item: T): void {\n this.buffer.push(item);\n if (this.buffer.length >= this.config.batchSize) {\n void this.flush();\n }\n }\n\n /** Flush manual vía `fetch`. Resuelve cuando termina (los retries son diferidos). */\n async flush(): Promise<void> {\n if (this.flushing || this.buffer.length === 0) return;\n\n this.flushing = true;\n const batch = this.buffer.splice(0, this.buffer.length);\n\n try {\n await this.config.transport.send('/v1/events', { events: batch });\n this.retryCount = 0;\n } catch (error) {\n // Re-encolar al INICIO para preservar el orden cronológico.\n this.buffer.unshift(...batch);\n this.scheduleRetry();\n this.config.onError?.(error as Error);\n } finally {\n this.flushing = false;\n }\n }\n\n /** Flush síncrono vía `sendBeacon`, para `pagehide`/`visibilitychange`. */\n flushBeacon(): void {\n if (this.buffer.length === 0) return;\n const batch = this.buffer.splice(0, this.buffer.length);\n const success = this.config.transport.sendBeacon('/v1/events', { events: batch });\n if (!success) {\n // La página se está cerrando; re-encolar es poco útil pero evita pérdida si no se cierra.\n this.buffer.unshift(...batch);\n }\n }\n\n /** Detiene timers internos. Llamar al destruir el cliente. */\n destroy(): void {\n if (this.timer) clearInterval(this.timer);\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.timer = null;\n this.retryTimer = null;\n }\n\n private startTimer(): void {\n this.timer = setInterval(() => {\n void this.flush();\n }, this.config.flushIntervalMs);\n }\n\n private scheduleRetry(): void {\n const maxRetries = this.config.maxRetries ?? 3;\n if (this.retryCount >= maxRetries) {\n this.retryCount = 0;\n return;\n }\n\n this.retryCount++;\n // Backoff exponencial: 1s, 2s, 4s, 8s... con tope de 30s, MÁS jitter.\n // Sin jitter, ante un 5xx del backend TODOS los clientes reintentan en\n // lockstep (1s, 2s, 4s…) y amplifican el pico justo cuando está degradado.\n // Equal jitter: mitad fija + mitad aleatoria → desincroniza la horda.\n const base = Math.min(1000 * 2 ** (this.retryCount - 1), RETRY_MAX_DELAY_MS);\n const delayMs = base / 2 + Math.random() * (base / 2);\n\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.retryTimer = setTimeout(() => {\n void this.flush();\n }, delayMs);\n }\n}\n","import { uuidv7 } from '../utils/uuid';\nimport type { StorageAdapter } from './storage';\n\nconst ANONYMOUS_ID_KEY = 'anonymous_user_id';\nconst END_USER_ID_KEY = 'end_user_id';\nconst SESSION_ID_KEY = 'session_id';\nconst SESSION_LAST_ACTIVE_KEY = 'session_last_active';\nconst SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutos\n\n/**\n * Gestiona la identidad triple del SDK:\n * - `anonymousId`: persiste indefinidamente (≥ 1 año).\n * - `endUserId`: presente tras `identify()`.\n * - `sessionId`: se renueva tras 30 min de inactividad.\n */\nexport class Session {\n private _anonymousId: string;\n private _sessionId: string;\n private _endUserId: string | null = null;\n\n constructor(private readonly storage: StorageAdapter) {\n this._anonymousId = this.loadOrCreateAnonymousId();\n this._sessionId = this.loadOrCreateSession();\n // Restaurar la identidad persistida: sin esto el SDK \"olvida\" al usuario\n // en cada recarga y los eventos posteriores caen al anonymous_id hasta\n // que la app vuelva a llamar identify(). Persistimos end_user_id en\n // setEndUserId(), así que también hay que rehidratarlo aquí.\n this._endUserId = this.storage.get(END_USER_ID_KEY);\n }\n\n get anonymousId(): string {\n return this._anonymousId;\n }\n\n get sessionId(): string {\n return this._sessionId;\n }\n\n get endUserId(): string | null {\n return this._endUserId;\n }\n\n /** ID a usar como visitor en eventos (end_user_id si está identificado, si no anonymous). */\n get effectiveUserId(): string {\n return this._endUserId ?? this._anonymousId;\n }\n\n setEndUserId(id: string): void {\n this._endUserId = id;\n this.storage.set(END_USER_ID_KEY, id);\n }\n\n /** Renueva el timestamp de actividad. Si pasaron > 30 min, genera nueva sesión. */\n touch(): void {\n const lastActive = this.storage.get(SESSION_LAST_ACTIVE_KEY);\n const now = Date.now();\n\n if (lastActive && now - Number.parseInt(lastActive, 10) > SESSION_TIMEOUT_MS) {\n this._sessionId = uuidv7();\n this.storage.set(SESSION_ID_KEY, this._sessionId);\n }\n\n this.storage.set(SESSION_LAST_ACTIVE_KEY, String(now));\n }\n\n /** Limpia la identidad (reset) pero conserva el anonymous_id. */\n reset(): void {\n this._endUserId = null;\n this.storage.remove(END_USER_ID_KEY);\n // Regenerar sesión.\n this._sessionId = uuidv7();\n this.storage.set(SESSION_ID_KEY, this._sessionId);\n this.storage.set(SESSION_LAST_ACTIVE_KEY, String(Date.now()));\n }\n\n private loadOrCreateAnonymousId(): string {\n let id = this.storage.get(ANONYMOUS_ID_KEY);\n if (!id) {\n id = uuidv7();\n this.storage.set(ANONYMOUS_ID_KEY, id);\n }\n return id;\n }\n\n private loadOrCreateSession(): string {\n const existing = this.storage.get(SESSION_ID_KEY);\n const lastActive = this.storage.get(SESSION_LAST_ACTIVE_KEY);\n\n if (existing && lastActive) {\n const elapsed = Date.now() - Number.parseInt(lastActive, 10);\n if (elapsed < SESSION_TIMEOUT_MS) {\n return existing;\n }\n }\n\n const newId = uuidv7();\n this.storage.set(SESSION_ID_KEY, newId);\n this.storage.set(SESSION_LAST_ACTIVE_KEY, String(Date.now()));\n return newId;\n }\n}\n","import { hasDocument, hasLocalStorage } from '../utils/safe-env';\n\n/**\n * Contrato común de todos los backends de almacenamiento persistente.\n * Las claves se guardan internamente con el prefijo `veo:`.\n */\nexport interface StorageAdapter {\n get(key: string): string | null;\n set(key: string, value: string, options?: { ttlMs?: number }): void;\n remove(key: string): void;\n /** Borra únicamente las claves del SDK (prefijo `veo:`). */\n clear(): void;\n}\n\nconst STORAGE_PREFIX = 'veo:';\n/** TTL por defecto para cookies (1 año), satisface la persistencia del anonymous id. */\nconst ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;\n\n/** Backend basado en `localStorage`. Persistencia indefinida (ignora `ttlMs`). */\nclass LocalStorageAdapter implements StorageAdapter {\n get(key: string): string | null {\n return localStorage.getItem(STORAGE_PREFIX + key);\n }\n\n set(key: string, value: string): void {\n try {\n localStorage.setItem(STORAGE_PREFIX + key, value);\n } catch {\n // Cuota llena o storage bloqueado: ignorar silenciosamente.\n }\n }\n\n remove(key: string): void {\n localStorage.removeItem(STORAGE_PREFIX + key);\n }\n\n clear(): void {\n const toRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith(STORAGE_PREFIX)) toRemove.push(key);\n }\n for (const key of toRemove) localStorage.removeItem(key);\n }\n}\n\n/** Lee y trocea `document.cookie`. Solo se invoca cuando hay `document`. */\nfunction readCookies(): string[] {\n const raw = document.cookie;\n return raw === '' ? [] : raw.split('; ');\n}\n\n/** Backend basado en cookies de primer nivel. Usa `ttlMs` (default 1 año). */\nclass CookieAdapter implements StorageAdapter {\n get(key: string): string | null {\n const name = `${STORAGE_PREFIX}${key}=`;\n for (const cookie of readCookies()) {\n if (cookie.startsWith(name)) {\n return decodeURIComponent(cookie.slice(name.length));\n }\n }\n return null;\n }\n\n set(key: string, value: string, options?: { ttlMs?: number }): void {\n const maxAgeSec = Math.floor((options?.ttlMs ?? ONE_YEAR_MS) / 1000);\n const secure =\n typeof location !== 'undefined' && location.protocol === 'https:' ? '; Secure' : '';\n // biome-ignore lint/suspicious/noDocumentCookie: necesitamos escritura síncrona y cero deps; la Cookie Store API es async y no universal.\n document.cookie = `${STORAGE_PREFIX}${key}=${encodeURIComponent(\n value,\n )}; Path=/; Max-Age=${maxAgeSec}; SameSite=Lax${secure}`;\n }\n\n remove(key: string): void {\n // biome-ignore lint/suspicious/noDocumentCookie: ver set(); expiramos la cookie con Max-Age=0.\n document.cookie = `${STORAGE_PREFIX}${key}=; Path=/; Max-Age=0; SameSite=Lax`;\n }\n\n clear(): void {\n for (const cookie of readCookies()) {\n const eq = cookie.indexOf('=');\n const name = eq === -1 ? cookie : cookie.slice(0, eq);\n if (name.startsWith(STORAGE_PREFIX)) {\n this.remove(name.slice(STORAGE_PREFIX.length));\n }\n }\n }\n}\n\n/** Backend en memoria. Fallback cuando no hay browser storage (SSR, incógnito). */\nclass MemoryAdapter implements StorageAdapter {\n private store = new Map<string, string>();\n\n get(key: string): string | null {\n return this.store.get(key) ?? null;\n }\n\n set(key: string, value: string): void {\n this.store.set(key, value);\n }\n\n remove(key: string): void {\n this.store.delete(key);\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n\n/**\n * Crea el adapter de almacenamiento, respetando la preferencia del usuario y\n * cayendo a la mejor alternativa disponible si la preferida no existe.\n */\nexport function createStorage(\n preferred: 'localStorage' | 'cookie' | 'memory' = 'localStorage',\n): StorageAdapter {\n if (preferred === 'localStorage' && hasLocalStorage()) return new LocalStorageAdapter();\n if (preferred === 'cookie' && hasDocument()) return new CookieAdapter();\n if (preferred === 'memory') return new MemoryAdapter();\n\n // Cadena de fallback.\n if (hasLocalStorage()) return new LocalStorageAdapter();\n if (hasDocument()) return new CookieAdapter();\n return new MemoryAdapter();\n}\n","import { hasNavigatorSendBeacon } from '../utils/safe-env';\n\nexport interface TransportConfig {\n apiUrl: string;\n apiKey: string;\n sdkVersion: string;\n timeoutMs?: number;\n}\n\n/** Error de transporte con el código HTTP asociado (0 si fue un fallo de red). */\nexport class TransportError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n ) {\n super(message);\n this.name = 'TransportError';\n }\n}\n\n/**\n * Capa de red del SDK. Envía JSON al backend vía `fetch` (con timeout) y\n * ofrece `sendBeacon` para descargas fiables al cerrar la página.\n */\nexport class Transport {\n constructor(private readonly config: TransportConfig) {}\n\n /** Envío normal con `fetch`. Lanza `TransportError` si la respuesta no es OK. */\n async send<T = unknown>(path: string, body: unknown): Promise<T> {\n const url = `${this.config.apiUrl}${path}`;\n const controller = new AbortController();\n const timeoutMs = this.config.timeoutMs ?? 10000;\n // Abortamos con un motivo explícito para que el log sea claro\n // (`TimeoutError`) en vez del confuso \"signal is aborted without reason\".\n const timeoutId = setTimeout(\n () =>\n controller.abort(new DOMException(`Veo request timeout (${timeoutMs}ms)`, 'TimeoutError')),\n timeoutMs,\n );\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Api-Key': this.config.apiKey,\n 'X-Sdk-Version': this.config.sdkVersion,\n },\n body: JSON.stringify(body),\n // NO usar `keepalive: true` en los flushes normales: tiene límites\n // estrictos del navegador (cuota de requests/64KB) y produce abortos\n // espurios cuando hay varios envíos seguidos. El envío fiable al cerrar\n // la página ya lo cubre `sendBeacon()` (ver Queue.flushBeacon).\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new TransportError(`HTTP ${response.status}`, response.status);\n }\n\n return (await response.json()) as T;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Envío con `navigator.sendBeacon`. Fire-and-forget, pensado para `pagehide`.\n * Como sendBeacon no admite headers, la API key viaja por query string.\n */\n sendBeacon(path: string, body: unknown): boolean {\n if (!hasNavigatorSendBeacon()) return false;\n\n const url = new URL(`${this.config.apiUrl}${path}`);\n url.searchParams.set('key', this.config.apiKey);\n url.searchParams.set('v', this.config.sdkVersion);\n\n const blob = new Blob([JSON.stringify(body)], { type: 'application/json' });\n return navigator.sendBeacon(url.toString(), blob);\n }\n}\n","import type { ActionPayload, ActionType, IdentifyRequest } from '../contract/v1';\nimport { DEFAULT_FLUSH_BATCH_SIZE, DEFAULT_FLUSH_INTERVAL_MS, SDK_VERSION } from '../contract/v1';\nimport type {\n VeoClient,\n VeoClientEventListener,\n VeoClientEventName,\n VeoClientEvents,\n VeoConfig,\n VeoOrganization,\n VeoPlugin,\n VeoVisitor,\n} from '../types';\nimport { hasDocument, hasWindow } from '../utils/safe-env';\nimport { uuidv7 } from '../utils/uuid';\nimport { resolveApiUrl } from './api-url';\nimport { Queue } from './queue';\nimport { Session } from './session';\nimport { createStorage, type StorageAdapter } from './storage';\nimport { Transport } from './transport';\n\nconst ORGANIZATION_ID_KEY = 'organization_id';\nconst END_USER_ID_KEY = 'end_user_id';\nconst IDENTIFY_SIG_KEY = 'identify_signature';\n\n/**\n * `JSON.stringify` con claves ordenadas (recursivo) para que la firma de\n * identidad sea estable sin importar el orden en que la app arme el objeto\n * de traits/attributes. Sin esto, `{a,b}` y `{b,a}` darían firmas distintas\n * y el identify se reenviaría sin que nada haya cambiado.\n */\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value) ?? 'null';\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`;\n const entries = Object.keys(value as Record<string, unknown>)\n .sort()\n .map((k) => `${JSON.stringify(k)}:${stableStringify((value as Record<string, unknown>)[k])}`);\n return `{${entries.join(',')}}`;\n}\n\n/** Campos opcionales que cada API pública aporta al construir el evento. */\ninterface EnqueueInput {\n actionType: ActionType;\n actionName?: string;\n pageUrl?: string;\n pagePath?: string;\n pageTitle?: string;\n pageReferrer?: string;\n actionProperties?: Record<string, unknown>;\n}\n\n/**\n * Cliente principal del SDK. Expone la API pública (`identify`, `track`,\n * `pageview`, `reset`, `flush`, `use`). Toda la API salvo `flush()` es síncrona:\n * los eventos se encolan y la llamada retorna de inmediato.\n */\nexport class Client implements VeoClient {\n readonly version = SDK_VERSION;\n private readonly transport: Transport;\n private readonly storage: StorageAdapter;\n private readonly session: Session;\n private readonly queue: Queue<ActionPayload>;\n private readonly plugins: VeoPlugin[] = [];\n private currentOrganizationId: string | null = null;\n private readonly listeners: {\n [E in VeoClientEventName]: Set<VeoClientEventListener<E>>;\n } = {\n pageview: new Set(),\n identify: new Set(),\n };\n\n constructor(private readonly config: VeoConfig) {\n if (!config.apiKey) throw new Error('apiKey is required');\n\n this.storage = createStorage(config.storage ?? 'localStorage');\n this.session = new Session(this.storage);\n\n this.transport = new Transport({\n apiKey: config.apiKey,\n apiUrl: resolveApiUrl(config).replace(/\\/$/, ''),\n sdkVersion: SDK_VERSION,\n });\n\n this.queue = new Queue<ActionPayload>({\n transport: this.transport,\n flushIntervalMs: config.flushInterval ?? DEFAULT_FLUSH_INTERVAL_MS,\n batchSize: config.flushBatchSize ?? DEFAULT_FLUSH_BATCH_SIZE,\n onError: (err) => {\n if (config.debug) console.error('[veo] flush error:', err);\n },\n });\n\n // Rehidratar identidad persistida.\n const persistedUserId = this.storage.get(END_USER_ID_KEY);\n if (persistedUserId) this.session.setEndUserId(persistedUserId);\n\n const persistedOrgId = this.storage.get(ORGANIZATION_ID_KEY);\n if (persistedOrgId) this.currentOrganizationId = persistedOrgId;\n\n this.setupUnloadHandlers();\n\n if (config.debug) {\n console.log('[veo] initialized', {\n anonymousId: this.session.anonymousId,\n sessionId: this.session.sessionId,\n endUserId: this.session.endUserId,\n });\n }\n }\n\n identify(payload: { visitor: VeoVisitor; organization?: VeoOrganization }): void {\n const { visitor, organization } = payload;\n\n // Idempotencia: si ya estamos identificados como este visitor y ni los\n // traits ni la organización cambiaron, no reenviamos. Esto evita el spam\n // de identify cuando la app lo llama en cada carga/navegación (un patrón\n // común y recomendado): el SDK absorbe la repetición en vez de generar un\n // evento `identify` y un POST /v1/identify por cada render.\n const signature = stableStringify({\n id: visitor.id,\n traits: visitor.traits ?? {},\n org: organization ? { id: organization.id, attributes: organization.attributes ?? {} } : null,\n });\n if (this.session.endUserId === visitor.id && this.storage.get(IDENTIFY_SIG_KEY) === signature) {\n if (this.config.debug) console.debug('[veo] identify: sin cambios, omitido');\n return;\n }\n\n // Capturar el anonymous previo ANTES de mutar la identidad, para el merge en backend.\n const previousAnonymousId =\n this.session.endUserId === null ? this.session.anonymousId : undefined;\n\n this.session.setEndUserId(visitor.id);\n if (organization) {\n this.currentOrganizationId = organization.id;\n this.storage.set(ORGANIZATION_ID_KEY, organization.id);\n }\n\n // 1. Upsert de traits/attributes en /v1/identify (fire-and-forget).\n const endUser: IdentifyRequest['endUser'] = {\n id: visitor.id,\n traits: visitor.traits ?? {},\n ...(previousAnonymousId !== undefined ? { anonymousId: previousAnonymousId } : {}),\n };\n const body: IdentifyRequest = {\n endUser,\n ...(organization\n ? { organization: { id: organization.id, attributes: organization.attributes ?? {} } }\n : {}),\n };\n void this.transport.send('/v1/identify', body).catch((err) => {\n if (this.config.debug) console.error('[veo] identify failed:', err);\n });\n\n // 2. Registrar el evento \"identify\" en el log de acciones.\n this.enqueue({\n actionType: 'identify',\n actionProperties: {\n traits: visitor.traits,\n organizationAttributes: organization?.attributes,\n },\n });\n\n this.storage.set(IDENTIFY_SIG_KEY, signature);\n\n this.emit('identify', { endUserId: visitor.id, sessionId: this.session.sessionId });\n }\n\n track(name: string, properties?: Record<string, unknown>): void {\n if (!name || typeof name !== 'string') {\n if (this.config.debug) console.error('[veo] track: name is required');\n return;\n }\n this.enqueue({\n actionType: 'track',\n actionName: name,\n ...(properties !== undefined ? { actionProperties: properties } : {}),\n });\n }\n\n pageview(path?: string): void {\n if (!hasDocument()) return;\n\n const url = window.location.href;\n const pagePath = path ?? window.location.pathname;\n\n this.enqueue({\n actionType: 'pageview',\n pageUrl: url,\n pagePath,\n pageTitle: document.title,\n pageReferrer: document.referrer,\n });\n\n this.emit('pageview', {\n url,\n path: pagePath,\n sessionId: this.session.sessionId,\n endUserId: this.session.endUserId,\n });\n }\n\n reset(): void {\n this.session.reset();\n this.currentOrganizationId = null;\n this.storage.remove(ORGANIZATION_ID_KEY);\n this.storage.remove(END_USER_ID_KEY);\n this.storage.remove(IDENTIFY_SIG_KEY);\n }\n\n flush(): Promise<void> {\n return this.queue.flush();\n }\n\n use(plugin: VeoPlugin): VeoClient {\n this.plugins.push(plugin);\n plugin.install(this);\n return this;\n }\n\n getEndUserId(): string | null {\n return this.session.endUserId;\n }\n\n getAnonymousId(): string {\n return this.session.anonymousId;\n }\n\n getSessionId(): string {\n return this.session.sessionId;\n }\n\n /**\n * Suscribe `listener` a `event`. Devuelve una función para desuscribir.\n * Los errores en listeners se logean en debug mode pero NO se propagan\n * (un plugin no debe poder romper a otro).\n */\n on<E extends VeoClientEventName>(event: E, listener: VeoClientEventListener<E>): () => void {\n this.listeners[event].add(listener);\n return () => {\n this.listeners[event].delete(listener);\n };\n }\n\n private emit<E extends VeoClientEventName>(event: E, payload: VeoClientEvents[E]): void {\n for (const listener of this.listeners[event]) {\n try {\n listener(payload);\n } catch (err) {\n if (this.config.debug) console.error(`[veo] listener for '${event}' failed:`, err);\n }\n }\n }\n\n /**\n * Construye el evento completo y lo agrega a la queue. Omite los campos\n * opcionales no definidos (exigido por `exactOptionalPropertyTypes`).\n * @internal\n */\n private enqueue(input: EnqueueInput): void {\n this.session.touch();\n\n const organizationId = this.currentOrganizationId ?? undefined;\n const pageUrl = input.pageUrl ?? (hasWindow() ? window.location.href : undefined);\n const pagePath = input.pagePath ?? (hasWindow() ? window.location.pathname : undefined);\n const pageTitle = input.pageTitle ?? (hasDocument() ? document.title : undefined);\n const pageReferrer = input.pageReferrer ?? (hasDocument() ? document.referrer : undefined);\n\n const event: ActionPayload = {\n actionId: uuidv7(),\n endUserId: this.session.effectiveUserId,\n sessionId: this.session.sessionId,\n actionType: input.actionType,\n occurredAt: new Date().toISOString(),\n ...(organizationId !== undefined ? { organizationId } : {}),\n ...(input.actionName !== undefined ? { actionName: input.actionName } : {}),\n ...(pageUrl !== undefined ? { pageUrl } : {}),\n ...(pagePath !== undefined ? { pagePath } : {}),\n ...(pageTitle !== undefined ? { pageTitle } : {}),\n ...(pageReferrer !== undefined ? { pageReferrer } : {}),\n ...(input.actionProperties !== undefined ? { actionProperties: input.actionProperties } : {}),\n };\n\n this.queue.add(event);\n }\n\n private setupUnloadHandlers(): void {\n if (!hasWindow()) return;\n\n window.addEventListener('pagehide', () => this.queue.flushBeacon());\n window.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n this.queue.flushBeacon();\n }\n });\n }\n}\n","import { autocapturePlugin } from '../plugins/autocapture';\nimport { spaRouterPlugin } from '../plugins/spa-router';\nimport { type ThemeDetectorApi, themeDetectPlugin } from '../plugins/theme-detect';\nimport type { VeoClient, VeoConfig } from '../types';\nimport { resolveApiUrl } from './api-url';\nimport { isBuilderMode, maybeLoadBuilder } from './builder-loader';\nimport { Client } from './client';\n\n/**\n * Setup común del cliente, compartido por el entry ESM/CJS (`index.ts`, guías\n * estáticas) y el IIFE (`veo.ts`, guías perezosas). NO importa el plugin de\n * guías: la instalación va por el callback `onGuides`, así el bundle IIFE puede\n * quedar sin los renderers.\n *\n * El detector de tema también llega por callback (`loadThemeDetector`): el core\n * solo lleva el planificador; el detector se descarga como mucho una vez al día.\n *\n * Hace: client + spa-router + autocapture, instala guías vía callback, asigna\n * `window.veo` drenando la cola del snippet, y dispara el loader del builder.\n */\nexport function setupClient(\n config: VeoConfig,\n onGuides: (client: VeoClient) => void,\n loadBuilder?: () => Promise<unknown>,\n loadThemeDetector?: () => Promise<ThemeDetectorApi | null>,\n): VeoClient {\n const client = new Client(config);\n\n client.use(spaRouterPlugin());\n\n if (config.autocapture !== false) {\n const autocaptureConfig = typeof config.autocapture === 'object' ? config.autocapture : {};\n client.use(autocapturePlugin(autocaptureConfig));\n }\n\n // Tema de la app (colores + fuentes) para el design system. En modo builder\n // no corre: ahí la página tiene encima el chrome del editor.\n if (config.detectTheme !== false && loadThemeDetector && !isBuilderMode()) {\n client.use(\n themeDetectPlugin({\n apiUrl: resolveApiUrl(config),\n apiKey: config.apiKey,\n loadDetector: loadThemeDetector,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n }\n\n // Guías (opt-in): el caller decide instalarlas sync (bundler) o lazy (IIFE).\n onGuides(client);\n\n if (typeof window !== 'undefined') {\n const stub = (window as unknown as { veo?: { _q?: unknown[][] } }).veo;\n const pending = stub?._q ?? [];\n\n (window as unknown as { veo: VeoClient }).veo = client;\n\n for (const entry of pending) {\n const [method, args] = entry;\n if (method === 'init') continue; // ya inicializado\n const fn = (client as unknown as Record<string, (...a: unknown[]) => unknown>)[\n method as string\n ];\n if (typeof fn === 'function') {\n try {\n fn.apply(client, Array.from(args as ArrayLike<unknown>));\n } catch (err) {\n if (config.debug) console.error('[veo] drain error:', err);\n }\n }\n }\n\n maybeLoadBuilder({\n ...(config.builderUrl !== undefined ? { builderUrl: config.builderUrl } : {}),\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n ...(config.apiKey !== undefined ? { apiKey: config.apiKey } : {}),\n apiUrl: resolveApiUrl(config),\n ...(loadBuilder ? { loadBuilder } : {}),\n });\n }\n\n return client;\n}\n","import type { ThemeDetectorApi } from '../plugins/theme-detect';\nimport { hasDocument, hasWindow } from '../utils/safe-env';\n\n/**\n * Carga perezosa del detector de tema (`veo-theme.js`) en el build IIFE: inyecta\n * el `<script>` derivando la URL del que cargó `veo.js`. Devuelve `null` si no\n * se puede (sin DOM, URL no derivable, error de red): la detección es\n * best-effort y nunca debe afectar a la app.\n */\nexport function loadThemeDetector(opts: {\n themeUrl?: string;\n debug?: boolean;\n}): Promise<ThemeDetectorApi | null> {\n if (!hasWindow() || !hasDocument()) return Promise.resolve(null);\n const win = window as unknown as { veoTheme?: ThemeDetectorApi };\n if (win.veoTheme) return Promise.resolve(win.veoTheme);\n\n const url = opts.themeUrl ?? deriveThemeUrl();\n if (!url) {\n if (opts.debug) console.warn('[veo] no pude resolver la URL de veo-theme.js');\n return Promise.resolve(null);\n }\n return new Promise((resolve) => {\n const script = document.createElement('script');\n script.src = url;\n script.async = true;\n script.addEventListener('load', () => resolve(win.veoTheme ?? null));\n script.addEventListener('error', () => {\n if (opts.debug) console.error('[veo] no pude cargar', url);\n resolve(null);\n });\n document.head.appendChild(script);\n });\n}\n\n/** Deriva `veo-theme.js` del `<script>` que cargó `veo.js`. */\nfunction deriveThemeUrl(): string | null {\n const scripts = document.querySelectorAll<HTMLScriptElement>('script[src]');\n for (const script of Array.from(scripts)) {\n if (/\\bveo(\\.min)?\\.js(\\?.*)?$/.test(script.src)) {\n return script.src.replace(/\\bveo(\\.min)?\\.js/, 'veo-theme$1.js');\n }\n }\n return null;\n}\n","/**\n * Entry IIFE (`veo.js`, global `window.veo`). Igual que `index.ts` pero las\n * GUÍAS se cargan PEREZOSAMENTE (bundle `veo-guides.js`) — solo con\n * `guides:true` o al usar `veo.preview()`. Así `veo.js` queda chico (core +\n * spa-router + autocapture); los renderers + Floating UI van aparte.\n *\n * Los consumidores por bundler usan `@veo/sdk` (entry `index.ts`, estático).\n */\nimport { resolveApiUrl } from './core/api-url';\nimport { isBuilderMode } from './core/builder-loader';\nimport { loadGuides, type VeoGuidesApi } from './core/guides-loader';\nimport { getPreviewToken } from './core/preview-loader';\nimport { setupClient } from './core/setup';\nimport { loadThemeDetector } from './core/theme-loader';\nimport type { PreviewGuideInput, PreviewHandle, PreviewResult } from './plugins/guides';\nimport type { VeoClient, VeoConfig } from './types';\n\nexport { SDK_VERSION } from './contract/v1';\nexport { Client } from './core/client';\nexport { autocapturePlugin } from './plugins/autocapture';\nexport { definePlugin } from './plugins/plugin';\nexport { spaRouterPlugin } from './plugins/spa-router';\nexport type {\n VeoAutocaptureConfig,\n VeoClient,\n VeoConfig,\n VeoOrganization,\n VeoPlugin,\n VeoVisitor,\n} from './types';\n\n/** Inicializa el SDK (IIFE). Las guías se cargan perezosamente. */\nexport function init(config: VeoConfig): VeoClient {\n const apiUrl = resolveApiUrl(config);\n return setupClient(\n config,\n (client) => {\n const ensureGuides = (): Promise<VeoGuidesApi | null> =>\n loadGuides({\n ...(config.guidesUrl !== undefined ? { guidesUrl: config.guidesUrl } : {}),\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n });\n\n // Plugin runtime (guides:true): cargar el bundle e instalar al resolver.\n // En modo builder o preview-por-link NO se instala: ahí pinta la preview,\n // y el runtime duplicaría/taparía con las guías live.\n const previewToken = getPreviewToken();\n if (config.guides === true && !isBuilderMode() && previewToken === null) {\n void ensureGuides().then((guides) => {\n if (!guides) return;\n client.use(\n guides.guidesPlugin({\n apiUrl,\n apiKey: config.apiKey,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n });\n }\n\n // Modo preview-por-link (`?veoPreview=<token>`): cargar el bundle de guías\n // y renderizar la guía del token como vista previa sobre la app real.\n if (previewToken !== null) {\n void ensureGuides().then((guides) =>\n guides?.runPreviewMode({\n apiKey: config.apiKey,\n apiUrl,\n token: previewToken,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n }\n\n // `veo.preview()` / `veo.closePreview()` cargan las guías on-demand y\n // mantienen el shape { close, ready } aunque el bundle resuelva async.\n (client as unknown as Record<string, unknown>).preview = (\n input: PreviewGuideInput,\n ): PreviewHandle => {\n let inner: PreviewHandle | null = null;\n const ready: Promise<PreviewResult> = ensureGuides().then((guides) => {\n if (!guides) return { rendered: false };\n inner = guides.previewGuide(input);\n return inner.ready;\n });\n return { close: () => inner?.close(), ready, host: () => inner?.host() ?? null };\n };\n (client as unknown as Record<string, unknown>).closePreview = (): void => {\n void ensureGuides().then((guides) => guides?.closeGuidePreview());\n };\n },\n undefined,\n // Detector de tema: bundle aparte (`veo-theme.js`), solo cuando toca detectar.\n () =>\n loadThemeDetector({\n ...(config.themeUrl !== undefined ? { themeUrl: config.themeUrl } : {}),\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n}\n"]}
|