veo-sdk 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/builder-loader.ts","../src/core/preview-loader.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/contract/v1.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/index.ts"],"names":["END_USER_ID_KEY"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\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';\n\n/** Debe coincidir con `BUILDER_TOKEN_PARAM` (bridge-protocol.ts). */\nconst BUILDER_TOKEN_PARAM = 'veoBuilder';\n\n/**\n * `true` cuando la app corre en modo builder (URL con `?veoBuilder=<token>`,\n * p.ej. dentro del iframe del editor del dashboard). En ese modo el editor\n * pinta las guías vía PREVIEW; el runtime NO debe resolver/renderizar las\n * guías `live` o se duplicarían (la live del runtime + la preview del editor).\n */\nexport function isBuilderMode(): boolean {\n if (!hasWindow()) return false;\n try {\n return new URLSearchParams(window.location.search).has(BUILDER_TOKEN_PARAM);\n } catch {\n return false;\n }\n}\n\nexport function maybeLoadBuilder(opts: {\n builderUrl?: string;\n debug?: boolean;\n apiKey?: string;\n apiUrl?: string;\n}): void {\n if (!hasWindow() || !hasDocument()) return;\n\n let params: URLSearchParams;\n try {\n params = new URLSearchParams(window.location.search);\n } catch {\n return;\n }\n if (!params.has(BUILDER_TOKEN_PARAM)) 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 (opts.debug) {\n console.warn('[veo] builder mode pedido pero no pude resolver la URL de veo-builder.js');\n }\n return;\n }\n if (document.querySelector(`script[src=\"${url}\"]`)) return;\n\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}\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 * 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/** Token del link de preview, o `null` si la URL no lo trae (o viene vacío). */\nexport function getPreviewToken(): string | null {\n if (!hasWindow()) return null;\n try {\n const value = new URLSearchParams(window.location.search).get(PREVIEW_TOKEN_PARAM);\n return value ? value : null;\n } catch {\n return null;\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","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 { 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\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 };\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.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 }\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 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","/**\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 * 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 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.\n const delayMs = Math.min(1000 * 2 ** (this.retryCount - 1), RETRY_MAX_DELAY_MS);\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 acá.\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 { 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 if (!config.apiUrl) throw new Error('apiUrl 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: config.apiUrl.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 { VeoClient, VeoConfig } from '../types';\nimport { 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 * 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(config: VeoConfig, onGuides: (client: VeoClient) => void): 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 // 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 ...(config.apiUrl !== undefined ? { apiUrl: config.apiUrl } : {}),\n });\n }\n\n return client;\n}\n","/**\n * @veo/sdk - SDK oficial de Veo para web (entry ESM/CJS para bundlers).\n *\n * Acá las guías se importan ESTÁTICAMENTE (el bundler las incluye/treeshake).\n * El entry IIFE (`veo.ts` → `veo.js`) las carga PEREZOSAMENTE para quedar chico.\n */\nimport { isBuilderMode } from './core/builder-loader';\nimport { getPreviewToken } from './core/preview-loader';\nimport { setupClient } from './core/setup';\nimport { closeGuidePreview, guidesPlugin, previewGuide, runPreviewMode } 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 type { PreviewGuideInput, PreviewHandle, PreviewResult } from './plugins/guides';\nexport { closeGuidePreview, guidesPlugin, previewGuide } from './plugins/guides';\nexport { definePlugin } from './plugins/plugin';\n// El element picker (inspector) vive en un bundle aparte para no inflar el SDK\n// de producción: `import { startElementPicker } from '@veo/sdk/builder'`.\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/**\n * Inicializa el SDK de Veo. Instala por defecto el plugin de SPA router\n * (auto-pageview) y, en browser, expone la instancia en `window.veo` drenando\n * la cola del snippet stub si existe.\n *\n * @example\n * ```ts\n * import { init } from '@veo/sdk';\n *\n * const veo = init({\n * apiKey: 'pk_xxx',\n * apiUrl: 'https://api.veo.io'\n * });\n *\n * veo.identify({ visitor: { id: 'user_123' } });\n * veo.track('button_clicked');\n * ```\n */\nexport function init(config: VeoConfig): VeoClient {\n return setupClient(config, (client) => {\n // Renderer de guías: opt-in. Reusa apiUrl/apiKey/debug del client.\n // En modo builder o preview-por-link NO se instala (ahí pinta la preview;\n // el runtime duplicaría/taparía con las guías live).\n const previewToken = getPreviewToken();\n if (config.guides === true && !isBuilderMode() && previewToken === null) {\n client.use(\n guidesPlugin({\n apiUrl: config.apiUrl,\n apiKey: config.apiKey,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n }\n\n // Modo preview-por-link (`?veoPreview=<token>`): renderiza la guía del\n // token como vista previa sobre la app real.\n if (previewToken !== null) {\n void runPreviewMode({\n apiKey: config.apiKey,\n apiUrl: config.apiUrl,\n token: previewToken,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n });\n }\n\n // Conveniencia: `veo.preview(def)` / `veo.closePreview()` en la instancia.\n (client as unknown as Record<string, unknown>).preview = previewGuide;\n (client as unknown as Record<string, unknown>).closePreview = closeGuidePreview;\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/contract/v1.ts","../src/core/api-url.ts","../src/core/builder-loader.ts","../src/core/preview-loader.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/core/queue.ts","../src/core/session.ts","../src/core/storage.ts","../src/core/transport.ts","../src/core/client.ts","../src/core/setup.ts","../src/index.ts"],"names":["END_USER_ID_KEY"],"mappings":"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","file":"index.mjs","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 acá 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 * 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 * 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/** Token del link de preview, o `null` si la URL no lo trae (o viene vacío). */\nexport function getPreviewToken(): string | null {\n if (!hasWindow()) return null;\n try {\n const value = new URLSearchParams(window.location.search).get(PREVIEW_TOKEN_PARAM);\n return value ? value : null;\n } catch {\n return null;\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","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 { 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\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 };\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.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 }\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 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 { 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.\n const delayMs = Math.min(1000 * 2 ** (this.retryCount - 1), RETRY_MAX_DELAY_MS);\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 acá.\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 { VeoClient, VeoConfig } from '../types';\nimport { resolveApiUrl } from './api-url';\nimport { 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 * 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): 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 // 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","/**\n * @veo/sdk - SDK oficial de Veo para web (entry ESM/CJS para bundlers).\n *\n * Acá las guías se importan ESTÁTICAMENTE (el bundler las incluye/treeshake).\n * El entry IIFE (`veo.ts` → `veo.js`) las carga PEREZOSAMENTE para quedar chico.\n */\nimport { resolveApiUrl } from './core/api-url';\nimport { isBuilderMode } from './core/builder-loader';\nimport { getPreviewToken } from './core/preview-loader';\nimport { setupClient } from './core/setup';\nimport { closeGuidePreview, guidesPlugin, previewGuide, runPreviewMode } 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 type { PreviewGuideInput, PreviewHandle, PreviewResult } from './plugins/guides';\nexport { closeGuidePreview, guidesPlugin, previewGuide } from './plugins/guides';\nexport { definePlugin } from './plugins/plugin';\n// El element picker (inspector) vive en un bundle aparte para no inflar el SDK\n// de producción: `import { startElementPicker } from '@veo/sdk/builder'`.\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/**\n * Inicializa el SDK de Veo. Instala por defecto el plugin de SPA router\n * (auto-pageview) y, en browser, expone la instancia en `window.veo` drenando\n * la cola del snippet stub si existe.\n *\n * @example\n * ```ts\n * import { init } from '@veo/sdk';\n *\n * // apiUrl es opcional: por defecto apunta al backend gestionado de Veo.\n * const veo = init({ apiKey: 'pk_xxx' });\n *\n * veo.identify({ visitor: { id: 'user_123' } });\n * veo.track('button_clicked');\n * ```\n */\nexport function init(config: VeoConfig): VeoClient {\n const apiUrl = resolveApiUrl(config);\n return setupClient(\n config,\n (client) => {\n // Renderer de guías: opt-in. Reusa apiUrl/apiKey/debug del client.\n // En modo builder o preview-por-link NO se instala (ahí pinta la preview;\n // el runtime duplicaría/taparía con las guías live).\n const previewToken = getPreviewToken();\n if (config.guides === true && !isBuilderMode() && previewToken === null) {\n client.use(\n guidesPlugin({\n apiUrl,\n apiKey: config.apiKey,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n }),\n );\n }\n\n // Modo preview-por-link (`?veoPreview=<token>`): renderiza la guía del\n // token como vista previa sobre la app real.\n if (previewToken !== null) {\n void runPreviewMode({\n apiKey: config.apiKey,\n apiUrl,\n token: previewToken,\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n });\n }\n\n // Conveniencia: `veo.preview(def)` / `veo.closePreview()` en la instancia.\n (client as unknown as Record<string, unknown>).preview = previewGuide;\n (client as unknown as Record<string, unknown>).closePreview = closeGuidePreview;\n },\n // Fallback de carga del builder para bundlers: `import()` dinámico → el bundler\n // lo code-splitea (solo se descarga en modo builder). Así el consumidor por\n // bundler NO necesita copiar `veo-builder.js` ni setear `builderUrl`.\n () => import('./plugins/builder').then((m) => m.initBuilderMode()),\n );\n}\n"]}
package/dist/next.cjs ADDED
@@ -0,0 +1,90 @@
1
+ 'use strict';
2
+
3
+ // src/core/builder-constants.ts
4
+ var BUILDER_TOKEN_PARAM = "veoBuilder";
5
+ var BUILDER_ORIGIN_PARAM = "veoBuilderOrigin";
6
+
7
+ // src/next.ts
8
+ var VEO_BUILDER_COOKIE = "veo-builder";
9
+ var VEO_BUILDER_ORIGIN_COOKIE = "veo-builder-origin";
10
+ function readVeoBuilderContext(request) {
11
+ const params = request.nextUrl.searchParams;
12
+ const fromParam = params.get(BUILDER_TOKEN_PARAM);
13
+ if (fromParam) {
14
+ return {
15
+ token: fromParam,
16
+ origin: params.get(BUILDER_ORIGIN_PARAM) ?? request.cookies.get(VEO_BUILDER_ORIGIN_COOKIE)?.value ?? null
17
+ };
18
+ }
19
+ const fromCookie = request.cookies.get(VEO_BUILDER_COOKIE)?.value;
20
+ if (fromCookie) {
21
+ return {
22
+ token: fromCookie,
23
+ origin: request.cookies.get(VEO_BUILDER_ORIGIN_COOKIE)?.value ?? null
24
+ };
25
+ }
26
+ return null;
27
+ }
28
+ async function ensureVeoDesignSession(builder, auth, options = {}) {
29
+ if (!builder) return;
30
+ const email = options.email ?? readEnv("VEO_BUILDER_DEMO_EMAIL");
31
+ const password = options.password ?? readEnv("VEO_BUILDER_DEMO_PASSWORD");
32
+ if (!email || !password) return;
33
+ const {
34
+ data: { user }
35
+ } = await auth.getUser();
36
+ if (!user) await auth.signInWithPassword({ email, password });
37
+ }
38
+ function readEnv(key) {
39
+ try {
40
+ return typeof process !== "undefined" ? process.env?.[key] : void 0;
41
+ } catch {
42
+ return void 0;
43
+ }
44
+ }
45
+ function veoBuilderProxy(handler, options = {}) {
46
+ return async (request) => {
47
+ const builder = readVeoBuilderContext(request);
48
+ const response = await handler(request, { builder });
49
+ if (builder) {
50
+ repartitionCookies(response);
51
+ persistBuilderCookies(response, builder, options.cookieMaxAge ?? 1800);
52
+ applyFramingHeaders(response, builder, options.dashboardOrigins);
53
+ }
54
+ return response;
55
+ };
56
+ }
57
+ function repartitionCookies(response) {
58
+ for (const cookie of response.cookies.getAll()) {
59
+ response.cookies.set({ ...cookie, sameSite: "none", secure: true, partitioned: true });
60
+ }
61
+ }
62
+ function persistBuilderCookies(response, ctx, maxAge) {
63
+ const base = { path: "/", maxAge, sameSite: "none", secure: true, partitioned: true };
64
+ response.cookies.set({ name: VEO_BUILDER_COOKIE, value: ctx.token, httpOnly: true, ...base });
65
+ if (ctx.origin) {
66
+ response.cookies.set({
67
+ name: VEO_BUILDER_ORIGIN_COOKIE,
68
+ value: ctx.origin,
69
+ httpOnly: false,
70
+ ...base
71
+ });
72
+ }
73
+ }
74
+ function applyFramingHeaders(response, ctx, dashboardOrigins) {
75
+ const configured = (dashboardOrigins ?? []).map((s) => s.trim()).filter(Boolean);
76
+ const origins = configured.length > 0 ? configured : ctx.origin ? [ctx.origin] : [];
77
+ response.headers.delete("X-Frame-Options");
78
+ response.headers.set(
79
+ "Content-Security-Policy",
80
+ `frame-ancestors 'self' ${origins.join(" ")}`.trim()
81
+ );
82
+ }
83
+
84
+ exports.VEO_BUILDER_COOKIE = VEO_BUILDER_COOKIE;
85
+ exports.VEO_BUILDER_ORIGIN_COOKIE = VEO_BUILDER_ORIGIN_COOKIE;
86
+ exports.ensureVeoDesignSession = ensureVeoDesignSession;
87
+ exports.readVeoBuilderContext = readVeoBuilderContext;
88
+ exports.veoBuilderProxy = veoBuilderProxy;
89
+ //# sourceMappingURL=next.cjs.map
90
+ //# sourceMappingURL=next.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/builder-constants.ts","../src/next.ts"],"names":[],"mappings":"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","file":"next.cjs","sourcesContent":["/**\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 */\nexport const BUILDER_TOKEN_PARAM = 'veoBuilder';\nexport const BUILDER_ORIGIN_PARAM = 'veoBuilderOrigin';\n","/**\n * `veo-sdk/next` — helper de middleware para el \"modo diseño\" del editor visual.\n *\n * El editor de Veo embebe tu app en un `<iframe>` con `?veoBuilder=<token>`. Para\n * que tu app se deje diseñar hacen falta 3 cosas MECÁNICAS:\n * 1. permitir el embed (`frame-ancestors`, sacar `X-Frame-Options`),\n * 2. que las cookies de sesión viajen en el iframe cross-site\n * (`SameSite=None; Secure; Partitioned` — CHIPS),\n * 3. persistir el modo builder entre navegaciones (cookie particionada), así\n * sobrevive al redirect del guard de auth y a un login.\n *\n * Este wrapper hace las 3. Lo ÚNICO app-specific — qué sesión renderizás sin\n * login (usuario demo, etc.) — queda en tu handler, que recibe `{ builder }`.\n *\n * No depende de `next` (usa tipos estructurales), así el SDK sigue sin\n * dependencias de runtime. `NextRequest`/`NextResponse` son compatibles.\n *\n * @example\n * ```ts\n * // middleware.ts (o proxy.ts en Next 16)\n * import { veoBuilderProxy } from 'veo-sdk/next';\n *\n * export default veoBuilderProxy(\n * async (request, { builder }) => {\n * const { supabase, response } = createSupabaseMiddleware(request);\n * const { data: { user } } = await supabase.auth.getUser();\n * // Lo único tuyo: la sesión de diseño cuando estás embebido y sin login.\n * if (builder && !user) {\n * await supabase.auth.signInWithPassword({\n * email: process.env.VEO_BUILDER_DEMO_EMAIL!,\n * password: process.env.VEO_BUILDER_DEMO_PASSWORD!,\n * });\n * }\n * return response;\n * },\n * { dashboardOrigins: [process.env.VEO_DASHBOARD_ORIGINS ?? ''] },\n * );\n * ```\n */\nimport { BUILDER_ORIGIN_PARAM, BUILDER_TOKEN_PARAM } from './core/builder-constants';\n\n/** Cookie que persiste el token del builder (particionada, contexto embebido). */\nexport const VEO_BUILDER_COOKIE = 'veo-builder';\n/** Cookie que persiste el origen del dashboard de Veo. */\nexport const VEO_BUILDER_ORIGIN_COOKIE = 'veo-builder-origin';\n\n/** Sesión de builder activa (la app está embebida por el editor de Veo). */\nexport interface VeoBuilderContext {\n /** Token de correlación del handshake (idealmente firmado por el backend). */\n token: string;\n /** Origen del dashboard que embebe, para `frame-ancestors`. */\n origin: string | null;\n}\n\n// ── Tipos estructurales, compatibles con NextRequest/NextResponse ──\ninterface CookieLike {\n name: string;\n value: string;\n path?: string;\n domain?: string;\n maxAge?: number;\n expires?: Date | number;\n httpOnly?: boolean;\n sameSite?: boolean | 'lax' | 'strict' | 'none';\n secure?: boolean;\n partitioned?: boolean;\n priority?: 'low' | 'medium' | 'high';\n}\n\nexport interface VeoBuilderRequest {\n nextUrl: { searchParams: URLSearchParams };\n cookies: { get(name: string): { value: string } | undefined };\n}\n\nexport interface VeoBuilderResponse {\n headers: { set(name: string, value: string): void; delete(name: string): void };\n cookies: {\n set(cookie: CookieLike): void;\n getAll(): CookieLike[];\n };\n}\n\nexport interface VeoBuilderProxyOptions {\n /**\n * Orígenes autorizados a embeber la app (`frame-ancestors`), p.ej.\n * `['https://veo-dashboard-opal.vercel.app']`. Si se omite o queda vacío, se\n * usa el origen que envía el propio editor (`veoBuilderOrigin`).\n */\n dashboardOrigins?: string[];\n /** TTL de las cookies del modo builder, en segundos. Default 1800 (30 min). */\n cookieMaxAge?: number;\n}\n\n/**\n * Lee el contexto de builder del request: del query param (`?veoBuilder`, primer\n * arranque dentro del iframe) o de la cookie (sobrevive navegaciones SPA y\n * requests RSC que ya no llevan el param). `null` si la app corre en modo normal.\n */\nexport function readVeoBuilderContext(request: VeoBuilderRequest): VeoBuilderContext | null {\n const params = request.nextUrl.searchParams;\n const fromParam = params.get(BUILDER_TOKEN_PARAM);\n if (fromParam) {\n return {\n token: fromParam,\n origin:\n params.get(BUILDER_ORIGIN_PARAM) ??\n request.cookies.get(VEO_BUILDER_ORIGIN_COOKIE)?.value ??\n null,\n };\n }\n const fromCookie = request.cookies.get(VEO_BUILDER_COOKIE)?.value;\n if (fromCookie) {\n return {\n token: fromCookie,\n origin: request.cookies.get(VEO_BUILDER_ORIGIN_COOKIE)?.value ?? null,\n };\n }\n return null;\n}\n\n/** Cliente de auth mínimo para la sesión de diseño. Compatible con `supabase.auth`\n * y cualquier auth con la misma forma (tipos estructurales, sin acoplar el SDK). */\nexport interface DesignAuthClient {\n getUser(): Promise<{ data: { user: unknown } }>;\n signInWithPassword(credentials: { email: string; password: string }): Promise<unknown>;\n}\n\nexport interface DesignSessionOptions {\n /** Email del usuario demo. Default: env `VEO_BUILDER_DEMO_EMAIL`. */\n email?: string;\n /** Password del usuario demo. Default: env `VEO_BUILDER_DEMO_PASSWORD`. */\n password?: string;\n}\n\n/**\n * Establece la \"sesión de diseño\" cuando la app está embebida por el editor de\n * Veo y no hay login: entra como usuario DEMO (sin datos reales) para poder\n * navegar la app sin auth. No-op fuera de modo builder, si ya hay sesión, o si\n * faltan credenciales. Agnóstico del proveedor: funciona con `supabase.auth` y\n * cualquier cliente con `getUser` + `signInWithPassword`.\n *\n * @example\n * ```ts\n * await ensureVeoDesignSession(builder, supabase.auth);\n * ```\n */\nexport async function ensureVeoDesignSession(\n builder: VeoBuilderContext | null,\n auth: DesignAuthClient,\n options: DesignSessionOptions = {},\n): Promise<void> {\n if (!builder) return;\n const email = options.email ?? readEnv('VEO_BUILDER_DEMO_EMAIL');\n const password = options.password ?? readEnv('VEO_BUILDER_DEMO_PASSWORD');\n if (!email || !password) return;\n const {\n data: { user },\n } = await auth.getUser();\n if (!user) await auth.signInWithPassword({ email, password });\n}\n\nfunction readEnv(key: string): string | undefined {\n try {\n return typeof process !== 'undefined' ? process.env?.[key] : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Envuelve tu middleware de Next para habilitar el modo diseño de Veo. Cuando la\n * app está embebida (`?veoBuilder` o cookie), DESPUÉS de correr tu handler:\n * - reescribe TODAS las cookies de la respuesta a `SameSite=None; Secure;\n * Partitioned` (así la sesión viaja en el iframe cross-site),\n * - persiste token + origen en cookies particionadas,\n * - setea `frame-ancestors` y saca `X-Frame-Options`.\n *\n * Tu handler recibe `{ builder }` para decidir la sesión de diseño (lo único\n * app-specific). Fuera de modo builder es un passthrough exacto (no toca nada).\n */\nexport function veoBuilderProxy<Req extends VeoBuilderRequest, Res extends VeoBuilderResponse>(\n handler: (request: Req, ctx: { builder: VeoBuilderContext | null }) => Res | Promise<Res>,\n options: VeoBuilderProxyOptions = {},\n): (request: Req) => Promise<Res> {\n return async (request: Req): Promise<Res> => {\n const builder = readVeoBuilderContext(request);\n const response = await handler(request, { builder });\n if (builder) {\n repartitionCookies(response);\n persistBuilderCookies(response, builder, options.cookieMaxAge ?? 1800);\n applyFramingHeaders(response, builder, options.dashboardOrigins);\n }\n return response;\n };\n}\n\n/** Reescribe todas las cookies de la respuesta a particionadas (CHIPS). */\nfunction repartitionCookies(response: VeoBuilderResponse): void {\n for (const cookie of response.cookies.getAll()) {\n response.cookies.set({ ...cookie, sameSite: 'none', secure: true, partitioned: true });\n }\n}\n\nfunction persistBuilderCookies(\n response: VeoBuilderResponse,\n ctx: VeoBuilderContext,\n maxAge: number,\n): void {\n const base = { path: '/', maxAge, sameSite: 'none' as const, secure: true, partitioned: true };\n response.cookies.set({ name: VEO_BUILDER_COOKIE, value: ctx.token, httpOnly: true, ...base });\n if (ctx.origin) {\n response.cookies.set({\n name: VEO_BUILDER_ORIGIN_COOKIE,\n value: ctx.origin,\n httpOnly: false,\n ...base,\n });\n }\n}\n\nfunction applyFramingHeaders(\n response: VeoBuilderResponse,\n ctx: VeoBuilderContext,\n dashboardOrigins?: string[],\n): void {\n const configured = (dashboardOrigins ?? []).map((s) => s.trim()).filter(Boolean);\n const origins = configured.length > 0 ? configured : ctx.origin ? [ctx.origin] : [];\n response.headers.delete('X-Frame-Options');\n response.headers.set(\n 'Content-Security-Policy',\n `frame-ancestors 'self' ${origins.join(' ')}`.trim(),\n );\n}\n"]}