veo-sdk 0.5.19 → 0.5.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veo-sdk",
3
- "version": "0.5.19",
3
+ "version": "0.5.21",
4
4
  "description": "Veo SDK - Product analytics and in-app guides for web apps",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -1,5 +0,0 @@
1
- export { VEO_BLOCK_MIME, attachBlockDropTarget, attachDesignManipulator, createBuilderSession, initBuilderMode, startElementPicker, stopElementPicker } from './chunk-345TTBZM.mjs';
2
- import './chunk-JRUCBH2I.mjs';
3
- import './chunk-PTG3BTJE.mjs';
4
- //# sourceMappingURL=builder-Q3V33JIO.mjs.map
5
- //# sourceMappingURL=builder-Q3V33JIO.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/plugins/builder/block-drop-target.ts","../src/plugins/builder/bridge-protocol.ts","../src/plugins/builder/builder-panel.ts","../src/plugins/builder/design-manipulator.ts","../src/plugins/builder/element-picker.ts","../src/plugins/builder/builder-mode.ts","../src/plugins/builder/builder-session.ts"],"names":["MIN_W","MIN_H","clamp"],"mappings":"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","file":"chunk-345TTBZM.mjs","sourcesContent":["/**\n * Drop-target de bloques sobre la preview (editor in-app).\n *\n * El autor arrastra un bloque de la paleta del panel (iframe del dashboard) y\n * lo suelta SOBRE la guía pintada en la app. El drag & drop HTML5 cruza\n * iframes de forma nativa, así que acá solo escuchamos `dragover`/`drop` en el\n * host de la guía, mostramos una línea de inserción entre bloques y avisamos\n * dónde cayó (el panel inserta el bloque en su estado y re-previsualiza).\n *\n * Contrato con el panel: el MIME `application/x-veo-block`. El `dragstart` de\n * la paleta lo setea con el tipo de bloque; durante `dragover` solo los TYPES\n * del dataTransfer son visibles (el valor recién se puede leer en el `drop`) —\n * alcanza para filtrar drags ajenos.\n *\n * La posición se expresa como `beforeIndex`: índice del bloque del paso ANTES\n * del cual insertar (`null` = al final). Los renderers estampan\n * `data-veo-idx` en cada elemento top-level con el índice ORIGINAL dentro de\n * `step.blocks[]` (una fila de botones agrupados lleva el del primero), así el\n * índice sobrevive a bloques filtrados u ocultos (p.ej. botones en pasos de\n * tour).\n */\n\nexport const VEO_BLOCK_MIME = 'application/x-veo-block';\n\n/** Dónde soltó el autor un bloque nuevo. */\nexport interface BlockDropPayload {\n stepIndex: number;\n /** Tipo de bloque arrastrado (title/text/button/image — lo valida el panel). */\n blockType: string;\n /** Índice del bloque ANTES del cual insertar; `null` = al final. */\n beforeIndex: number | null;\n}\n\nexport interface BlockDropTargetHandle {\n /**\n * Drag por POINTER (el camino principal): el panel manda las coordenadas del\n * puntero ya convertidas a la página de la app. Muestra/mueve la línea de\n * inserción; devuelve `true` si el punto está sobre la guía.\n */\n hoverAt(x: number, y: number): boolean;\n /**\n * Suelta en esas coordenadas: devuelve el punto de inserción, o `null` si el\n * puntero no estaba sobre la guía (el drop se descarta). Siempre borra la línea.\n */\n dropAt(x: number, y: number): { beforeIndex: number | null } | null;\n /** Cancela el hover (borra la línea sin soltar). */\n cancelHover(): void;\n detach(): void;\n}\n\ninterface AttachOptions {\n host: HTMLElement;\n stepIndex: number;\n onDrop: (payload: BlockDropPayload) => void;\n}\n\n/** Punto de inserción calculado bajo el cursor. */\ninterface DropSpot {\n beforeIndex: number | null;\n /** Coordenada Y (viewport) de la línea indicadora. */\n y: number;\n rect: DOMRect;\n}\n\n/**\n * Adjunta el drop-target al host de la guía en preview. Devuelve un handle\n * para desmontarlo (cambio de preview / cierre del editor).\n */\nexport function attachBlockDropTarget(options: AttachOptions): BlockDropTargetHandle {\n const { host, stepIndex, onDrop } = options;\n const doc = host.ownerDocument;\n let line: HTMLElement | null = null;\n let spot: DropSpot | null = null;\n\n const contentEl = (): HTMLElement | null =>\n host.shadowRoot?.querySelector<HTMLElement>('.veo-guide-content') ?? null;\n\n /** Hijos top-level que representan bloques (estampados por los renderers). */\n const blockChildren = (container: HTMLElement): HTMLElement[] =>\n Array.from(container.children).filter(\n (el): el is HTMLElement => el instanceof HTMLElement && el.dataset.veoIdx !== undefined,\n );\n\n const hideLine = (): void => {\n line?.remove();\n line = null;\n spot = null;\n };\n\n const showLine = (at: DropSpot): void => {\n if (!line) {\n line = doc.createElement('div');\n // Inline (no hay hoja de estilos del builder en el shadow de la guía).\n line.style.cssText =\n 'position:fixed;height:3px;border-radius:2px;background:#FF5B35;' +\n 'box-shadow:0 0 0 1px rgba(255,255,255,0.65);pointer-events:none;z-index:2147483647;';\n host.shadowRoot?.appendChild(line);\n }\n line.style.left = `${at.rect.left + 4}px`;\n line.style.width = `${Math.max(0, at.rect.width - 8)}px`;\n line.style.top = `${at.y - 1.5}px`;\n };\n\n const isBlockDrag = (event: DragEvent): boolean => {\n const types = event.dataTransfer?.types;\n return !!types && Array.from(types).includes(VEO_BLOCK_MIME);\n };\n\n /** Margen alrededor del contenido dentro del cual el drop sigue activo. */\n const NEAR_PX = 48;\n\n /** Boundary de inserción más cercano al cursor (por el eje Y). */\n const locate = (clientY: number): DropSpot | null => {\n const container = contentEl();\n if (!container) return null;\n const rect = container.getBoundingClientRect();\n const kids = blockChildren(container);\n let beforeIndex: number | null = null;\n let y = kids.length === 0 ? rect.top + rect.height / 2 : 0;\n for (const kid of kids) {\n const r = kid.getBoundingClientRect();\n if (clientY < r.top + r.height / 2) {\n const idx = Number(kid.dataset.veoIdx);\n beforeIndex = Number.isFinite(idx) ? idx : null;\n y = r.top;\n break;\n }\n y = r.bottom; // el cursor quedó debajo: candidato \"después del último\"\n }\n return { beforeIndex, y, rect };\n };\n\n /** ¿El punto está sobre (o cerca de) el contenido de la guía? */\n const overContent = (x: number, y: number, rect: DOMRect): boolean =>\n x >= rect.left - NEAR_PX &&\n x <= rect.right + NEAR_PX &&\n y >= rect.top - NEAR_PX &&\n y <= rect.bottom + NEAR_PX;\n\n const hoverAt = (x: number, y: number): boolean => {\n const at = locate(y);\n if (!at || !overContent(x, y, at.rect)) {\n hideLine();\n return false;\n }\n spot = at;\n showLine(at);\n return true;\n };\n\n const dropAt = (x: number, y: number): { beforeIndex: number | null } | null => {\n const at = locate(y);\n hideLine();\n if (!at || !overContent(x, y, at.rect)) return null;\n return { beforeIndex: at.beforeIndex };\n };\n\n const onDragOver = (event: DragEvent): void => {\n if (!isBlockDrag(event)) return;\n const at = locate(event.clientY);\n if (!at) return;\n event.preventDefault(); // habilita el drop\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';\n spot = at;\n showLine(at);\n };\n\n const onDropEvent = (event: DragEvent): void => {\n if (!isBlockDrag(event)) return;\n event.preventDefault();\n const blockType = event.dataTransfer?.getData(VEO_BLOCK_MIME) ?? '';\n const at = spot ?? locate(event.clientY);\n hideLine();\n if (!blockType || !at) return;\n onDrop({ stepIndex, blockType, beforeIndex: at.beforeIndex });\n };\n\n const onDragLeave = (event: DragEvent): void => {\n // Solo al salir del host de verdad (los cruces internos del shadow se\n // re-targetean al host y no llegan acá).\n const to = event.relatedTarget;\n if (to instanceof Node && (to === host || host.contains(to))) return;\n hideLine();\n };\n\n host.addEventListener('dragover', onDragOver);\n host.addEventListener('drop', onDropEvent);\n host.addEventListener('dragleave', onDragLeave);\n\n return {\n hoverAt,\n dropAt,\n cancelHover: hideLine,\n detach(): void {\n host.removeEventListener('dragover', onDragOver);\n host.removeEventListener('drop', onDropEvent);\n host.removeEventListener('dragleave', onDragLeave);\n hideLine();\n },\n };\n}\n","/**\n * Contrato de mensajes del puente builder (app del cliente ↔ dashboard).\n * Ambos lados validan `event.origin` y que `token` coincida antes de actuar.\n *\n * Flujo:\n * 1. El dashboard abre la app con `?veoBuilder=<token>&veoBuilderOrigin=<origen>`.\n * 2. La app (veo-builder.js) postea `ready` a la ventana que la abrió.\n * 3. El dashboard manda comandos (`start-picker`, `preview`, …).\n * 4. La app responde con eventos (`picked`, `pick-cancelled`, …).\n */\nimport type { PreviewGuideInput } from '../guides/guide-preview';\nimport type { BlockDropPayload } from './block-drop-target';\nimport type { DesignPatch } from './design-manipulator';\nimport type { PickedElement } from './element-picker';\n\nexport const VEO_BUILDER_SOURCE = 'veo-builder';\n// Los nombres de los query params viven en el core (`builder-token.ts`), única\n// fuente de verdad compartida con el loader y el gate del runtime de guías.\nexport { BUILDER_ORIGIN_PARAM, BUILDER_TOKEN_PARAM } from '../../core/builder-token';\n\n/** Eventos que la app del cliente envía al dashboard. */\nexport type BuilderEvent =\n | { type: 'ready' }\n | { type: 'picked'; payload: PickedElement }\n | { type: 'pick-cancelled' }\n // Manipulación directa: el autor arrastró/redimensionó la guía en la app;\n // el panel mergea `payload.style` sobre el `style` del paso indicado.\n | { type: 'design-updated'; payload: DesignPatch }\n // Drag & drop de bloques: el autor soltó un bloque de la paleta SOBRE la\n // guía en preview; el panel lo inserta en `step.blocks[]` en esa posición.\n | { type: 'block-dropped'; payload: BlockDropPayload }\n | { type: 'closed' };\n\n/** Comandos que el dashboard/panel envía a la app del cliente. */\nexport type BuilderCommand =\n | { type: 'start-picker'; maxAncestors?: number; hint?: string }\n | { type: 'stop-picker' }\n // `editable: true` (editor in-app) adjunta drag/resize sobre la preview.\n | { type: 'preview'; guide: PreviewGuideInput; editable?: boolean }\n // Drag de un bloque de la paleta POR POINTER (el DnD HTML5 no cruza bien el\n // iframe del panel): el panel captura el puntero y streamea sus coordenadas\n // RELATIVAS AL IFRAME; la app las convierte con el rect del panel, mueve la\n // línea de inserción y en `drop` responde con el evento `block-dropped`.\n | {\n type: 'block-drag';\n phase: 'move' | 'drop' | 'cancel';\n x: number;\n y: number;\n blockType: string;\n label?: string;\n }\n | { type: 'close-preview' }\n | { type: 'teardown' }\n // Modo panel inyectado: el panel avisa que cargó y está listo para recibir\n // eventos; la app responde con `ready`. Resuelve la carrera de que el iframe\n // del panel todavía no tenga su listener cuando la app postea `ready`.\n | { type: 'panel-ready' };\n\n/** Sobre común: todo mensaje del puente lleva `source` + `token`. */\nexport interface BuilderEnvelope {\n source: typeof VEO_BUILDER_SOURCE;\n token: string;\n}\n\nexport type BuilderEventMessage = BuilderEnvelope & BuilderEvent;\nexport type BuilderCommandMessage = BuilderEnvelope & BuilderCommand;\n","/**\n * Modo \"panel inyectado\" (editor en la pestaña de la app).\n *\n * La app es la pestaña top-level (login real) y el editor de Veo se inyecta\n * ENCIMA como una tarjeta flotante **arrastrable y redimensionable** (un iframe\n * al dashboard). Además se puede **sacar a una ventana independiente** del\n * navegador (\"pop-out\").\n *\n * El panel corre en el origen del dashboard (sesión de Veo para guardar guías) y\n * habla con la app (`window.parent` si está anclado, `window.opener` si está en\n * ventana aparte) por el puente postMessage. Este módulo inyecta/gestiona el\n * panel y expone su ventana destino.\n */\nimport { hasDocument, hasWindow } from '../../utils/safe-env';\n\nconst DEFAULT_PANEL_PATH = '/guides/design';\nconst PANEL_W = 400;\nconst PANEL_H = 640;\nconst MIN_W = 320;\nconst MIN_H = 320;\nconst MARGIN = 16;\n\nexport interface BuilderPanelOptions {\n dashboardOrigin: string;\n token: string;\n appOrigin: string;\n guide: string | null;\n panelPath: string | null;\n onClose: () => void;\n}\n\nexport interface BuilderPanelHandle {\n /** Ventana destino de los mensajes: el iframe anclado o la ventana pop-out. */\n target(): Window | null;\n /**\n * Rect del IFRAME del panel en coordenadas de la página de la app, o `null`\n * si el editor está en pop-out (ventana aparte: no hay mapeo de coordenadas).\n * Lo usa el drag de bloques para convertir el puntero panel → página.\n */\n frameRect(): DOMRect | null;\n /** Quita el panel del DOM (y cierra la ventana pop-out si hay). */\n teardown(): void;\n}\n\n/** Inyecta el panel del editor (arrastrable, redimensionable, pop-out). */\nexport function injectBuilderPanel(opts: BuilderPanelOptions): BuilderPanelHandle {\n if (!hasWindow() || !hasDocument()) {\n return { target: () => null, frameRect: () => null, teardown: () => {} };\n }\n\n const panelUrl = buildPanelUrl(opts);\n\n const host = document.createElement('div');\n host.setAttribute('data-veo-builder-panel', '');\n const shadow = host.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = PANEL_CSS;\n\n const card = document.createElement('div');\n card.className = 'veo-panel';\n let left = Math.max(MARGIN, window.innerWidth - PANEL_W - MARGIN);\n let top = MARGIN;\n card.style.left = `${left}px`;\n card.style.top = `${top}px`;\n card.style.width = `${PANEL_W}px`;\n card.style.height = `${PANEL_H}px`;\n\n // Header: título + pop-out + cerrar.\n const header = document.createElement('div');\n header.className = 'veo-panel-header';\n const title = document.createElement('span');\n title.className = 'veo-panel-title';\n title.textContent = 'OnUser · Editor';\n const actions = document.createElement('div');\n actions.className = 'veo-panel-actions';\n const popout = document.createElement('button');\n popout.className = 'veo-panel-btn';\n popout.type = 'button';\n popout.title = 'Abrir en ventana aparte';\n popout.setAttribute('aria-label', 'Abrir en ventana aparte');\n popout.textContent = '⧉';\n const close = document.createElement('button');\n close.className = 'veo-panel-btn veo-panel-close';\n close.type = 'button';\n close.title = 'Cerrar';\n close.setAttribute('aria-label', 'Cerrar');\n close.textContent = '✕';\n actions.append(popout, close);\n header.append(title, actions);\n\n const iframe = document.createElement('iframe');\n iframe.className = 'veo-panel-frame';\n iframe.title = 'Editor de Veo';\n iframe.src = panelUrl;\n\n const grip = document.createElement('div');\n grip.className = 'veo-panel-resize';\n grip.setAttribute('aria-hidden', 'true');\n\n card.append(header, iframe, grip);\n shadow.append(style, card);\n document.body.appendChild(host);\n\n // ── Pop-out: sacar el editor a una ventana independiente ────────────────\n let popped: Window | null = null;\n let pollTimer: ReturnType<typeof setInterval> | undefined;\n\n const stopPoll = (): void => {\n if (pollTimer !== undefined) {\n clearInterval(pollTimer);\n pollTimer = undefined;\n }\n };\n\n close.addEventListener('click', () => opts.onClose());\n popout.addEventListener('click', () => {\n const win = window.open(\n panelUrl,\n 'veo-editor',\n `popup,width=${Math.round(card.offsetWidth)},height=${Math.round(card.offsetHeight) + 60}`,\n );\n if (!win) return; // bloqueado por el navegador\n popped = win;\n card.style.display = 'none'; // el editor ahora vive en la ventana aparte\n pollTimer = setInterval(() => {\n if (popped?.closed) {\n stopPoll();\n opts.onClose(); // cerrar la ventana = salir del modo editor\n }\n }, 600);\n });\n\n // ── Arrastre por el header ──────────────────────────────────────────────\n header.addEventListener('mousedown', (e) => {\n if ((e.target as HTMLElement)?.classList.contains('veo-panel-btn')) return;\n e.preventDefault();\n const sx = e.clientX;\n const sy = e.clientY;\n const ol = left;\n const ot = top;\n iframe.style.pointerEvents = 'none';\n const move = (ev: MouseEvent): void => {\n left = clamp(ol + (ev.clientX - sx), 0, Math.max(0, window.innerWidth - card.offsetWidth));\n top = clamp(ot + (ev.clientY - sy), 0, Math.max(0, window.innerHeight - 40));\n card.style.left = `${left}px`;\n card.style.top = `${top}px`;\n };\n const up = (): void => {\n window.removeEventListener('mousemove', move);\n window.removeEventListener('mouseup', up);\n iframe.style.pointerEvents = '';\n };\n window.addEventListener('mousemove', move);\n window.addEventListener('mouseup', up);\n });\n\n // ── Redimensionar por el grip (esquina inferior derecha) ────────────────\n grip.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const sx = e.clientX;\n const sy = e.clientY;\n const sw = card.offsetWidth;\n const sh = card.offsetHeight;\n iframe.style.pointerEvents = 'none';\n const move = (ev: MouseEvent): void => {\n card.style.width = `${clamp(sw + (ev.clientX - sx), MIN_W, window.innerWidth)}px`;\n card.style.height = `${clamp(sh + (ev.clientY - sy), MIN_H, window.innerHeight)}px`;\n };\n const up = (): void => {\n window.removeEventListener('mousemove', move);\n window.removeEventListener('mouseup', up);\n iframe.style.pointerEvents = '';\n };\n window.addEventListener('mousemove', move);\n window.addEventListener('mouseup', up);\n });\n\n return {\n target: () => (popped && !popped.closed ? popped : iframe.contentWindow),\n frameRect: () => (popped && !popped.closed ? null : iframe.getBoundingClientRect()),\n teardown: () => {\n stopPoll();\n if (popped && !popped.closed) popped.close();\n host.remove();\n },\n };\n}\n\nfunction clamp(v: number, min: number, max: number): number {\n return Math.min(Math.max(v, min), max);\n}\n\nfunction buildPanelUrl(opts: BuilderPanelOptions): string {\n const path = opts.panelPath ?? DEFAULT_PANEL_PATH;\n const url = new URL(path, opts.dashboardOrigin);\n url.searchParams.set('veoToken', opts.token);\n url.searchParams.set('veoApp', opts.appOrigin);\n if (opts.guide) url.searchParams.set('veoGuide', opts.guide);\n return url.toString();\n}\n\nconst PANEL_CSS = `\n:host { all: initial; }\n.veo-panel {\n position: fixed;\n min-width: ${MIN_W}px; min-height: ${MIN_H}px;\n max-width: 96vw; max-height: 94vh;\n display: flex; flex-direction: column;\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 12px 40px rgba(0,0,0,0.28);\n overflow: hidden;\n z-index: 2147483647;\n font-family: system-ui, -apple-system, sans-serif;\n}\n.veo-panel-header {\n flex: 0 0 auto;\n display: flex; align-items: center; justify-content: space-between;\n padding: 8px 10px 8px 12px;\n background: #1b1714; color: #f7f1eb;\n font-size: 13px; font-weight: 600;\n cursor: grab;\n}\n.veo-panel-header:active { cursor: grabbing; }\n.veo-panel-actions { display: flex; gap: 2px; }\n.veo-panel-btn {\n border: 0; background: transparent; color: #fff;\n font-size: 14px; cursor: pointer; line-height: 1;\n padding: 4px 7px; border-radius: 6px;\n}\n.veo-panel-btn:hover { background: rgba(255,255,255,0.15); }\n.veo-panel-frame { flex: 1 1 auto; width: 100%; border: 0; background: #fff; }\n.veo-panel-resize {\n position: absolute; right: 0; bottom: 0;\n width: 16px; height: 16px;\n cursor: nwse-resize;\n background:\n linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.25) 50%, rgba(0,0,0,0.25) 60%,\n transparent 60%, transparent 72%, rgba(0,0,0,0.25) 72%, rgba(0,0,0,0.25) 82%, transparent 82%);\n}\n`;\n","/**\n * Manipulación DIRECTA del diseño en modo editor: arrastrar la tarjeta de una\n * modal para posicionarla, redimensionarla desde bordes/esquinas, y arrastrar\n * un banner para alternar top/bottom. Vive en el bundle builder (veo-builder.js)\n * — el runtime de guías no carga nada de esto.\n *\n * Funciona como DECORATOR: se adjunta DESPUÉS del render sobre el shadow root\n * abierto del host de la guía (no toca los renderers). Durante el gesto aplica\n * las variables CSS localmente (feedback a 60fps, sin postMessage); al soltar\n * (`pointerup`) emite UN `onCommit(patch)` con los valores finales, que el\n * builder-mode postea al panel como `design-updated`. El panel actualiza su\n * estado y re-manda `preview` — que entra por el update in-place con las\n * MISMAS variables → no hay loop ni parpadeo.\n *\n * Geometría del modal (ver styles.ts): la card usa `left: posX%` +\n * `translate(-posX%)`, o sea `cardLeft = posX * (viewportW - cardW)` →\n * `posX = cardLeft / (viewportW - cardW)`. Mismo modelo que serializa el\n * dashboard (`style.posX/posY` en 0..1) y consume `applyDesignVars`.\n */\nimport type { GuideType } from '../guides/types';\n\n/** Merge superficial sobre `step.style` del paso activo (lo aplica el panel). */\nexport interface DesignPatch {\n stepIndex: number;\n style: {\n posX?: number;\n posY?: number;\n width?: number;\n height?: number;\n position?: 'top' | 'bottom';\n };\n}\n\nexport interface DesignManipulatorOptions {\n /** Host de la guía (de `PreviewHandle.host()`), con shadow root abierto. */\n host: HTMLElement;\n guideType: GuideType;\n stepIndex: number;\n /** Se emite UNA vez por gesto, al soltar. */\n onCommit: (patch: DesignPatch) => void;\n /** Fin de cualquier gesto (con o sin cambios). Para aplicar previews encolados. */\n onGestureEnd?: () => void;\n}\n\nexport interface DesignManipulatorHandle {\n /** `true` mientras hay un gesto de drag/resize en curso. */\n isDragging(): boolean;\n /** Remueve handles, estilos y listeners. Idempotente. */\n detach(): void;\n}\n\nconst MIN_W = 220;\nconst MAX_W = 720;\nconst MIN_H = 120;\nconst MAX_H = 900;\n/** Zonas de agarre de los bordes (px). */\nconst EDGE = 8;\n\ntype ResizeDir = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';\nconst RESIZE_DIRS: ResizeDir[] = ['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'];\n\nconst MANIPULATOR_CSS = `\n.veo-mnp-card {\n outline: 1.5px dashed rgba(255, 91, 53, 0.75);\n outline-offset: 2px;\n}\n.veo-mnp-card:hover { cursor: move; }\n.veo-mnp-handle {\n position: absolute;\n z-index: 10;\n background: transparent;\n}\n.veo-mnp-handle::after {\n content: '';\n position: absolute;\n width: 8px; height: 8px;\n background: #fff;\n border: 1.5px solid rgba(255, 91, 53, 0.9);\n border-radius: 2px;\n top: 50%; left: 50%;\n transform: translate(-50%, -50%);\n opacity: 0;\n transition: opacity 100ms ease;\n}\n.veo-mnp-card:hover .veo-mnp-handle::after,\n.veo-mnp-handle:hover::after { opacity: 1; }\n.veo-mnp-n { top: -${EDGE / 2}px; left: ${EDGE}px; right: ${EDGE}px; height: ${EDGE}px; cursor: ns-resize; }\n.veo-mnp-s { bottom: -${EDGE / 2}px; left: ${EDGE}px; right: ${EDGE}px; height: ${EDGE}px; cursor: ns-resize; }\n.veo-mnp-e { right: -${EDGE / 2}px; top: ${EDGE}px; bottom: ${EDGE}px; width: ${EDGE}px; cursor: ew-resize; }\n.veo-mnp-w { left: -${EDGE / 2}px; top: ${EDGE}px; bottom: ${EDGE}px; width: ${EDGE}px; cursor: ew-resize; }\n.veo-mnp-ne { top: -${EDGE / 2}px; right: -${EDGE / 2}px; width: ${EDGE * 1.5}px; height: ${EDGE * 1.5}px; cursor: nesw-resize; }\n.veo-mnp-nw { top: -${EDGE / 2}px; left: -${EDGE / 2}px; width: ${EDGE * 1.5}px; height: ${EDGE * 1.5}px; cursor: nwse-resize; }\n.veo-mnp-se { bottom: -${EDGE / 2}px; right: -${EDGE / 2}px; width: ${EDGE * 1.5}px; height: ${EDGE * 1.5}px; cursor: nwse-resize; }\n.veo-mnp-sw { bottom: -${EDGE / 2}px; left: -${EDGE / 2}px; width: ${EDGE * 1.5}px; height: ${EDGE * 1.5}px; cursor: nesw-resize; }\n.veo-mnp-banner { outline: 1.5px dashed rgba(255, 91, 53, 0.75); outline-offset: -2px; cursor: grab; }\n.veo-mnp-banner:active { cursor: grabbing; }\n`;\n\nfunction clamp(v: number, min: number, max: number): number {\n return Math.min(Math.max(v, min), max);\n}\n\nfunction round3(v: number): number {\n return Math.round(v * 1000) / 1000;\n}\n\n/** true si el mousedown cayó sobre algo interactivo (no iniciar drag ahí). */\nfunction isInteractive(target: EventTarget | null): boolean {\n return Boolean(\n target instanceof Element && target.closest('button, a, input, textarea, select, label'),\n );\n}\n\n/**\n * Adjunta la manipulación directa al host de una guía montada. Devuelve el\n * handle, o `null` si el tipo de guía no la soporta o el DOM esperado no está.\n * Idempotente: si la card ya está decorada, no re-adjunta.\n */\nexport function attachDesignManipulator(\n opts: DesignManipulatorOptions,\n): DesignManipulatorHandle | null {\n const shadow = opts.host.shadowRoot;\n if (!shadow) return null;\n\n const card = shadow.querySelector<HTMLElement>('.veo-modal-card');\n if (card) return attachModal(opts, shadow, card);\n\n const banner = shadow.querySelector<HTMLElement>('.veo-banner');\n // El banner embebido se posiciona con prepend/append en el contenedor: su\n // top/bottom se cambia desde el panel (remonta). Solo el fijo se arrastra.\n if (banner && !banner.classList.contains('veo-banner-embedded')) {\n return attachBanner(opts, shadow, banner);\n }\n\n return null;\n}\n\n// ── Modal: drag libre + resize por 8 handles ────────────────────────────────\n\nfunction attachModal(\n opts: DesignManipulatorOptions,\n shadow: ShadowRoot,\n card: HTMLElement,\n): DesignManipulatorHandle | null {\n if (card.dataset.veoManipulated === '1') return null;\n card.dataset.veoManipulated = '1';\n card.classList.add('veo-mnp-card');\n\n const doc = card.ownerDocument;\n const style = doc.createElement('style');\n style.textContent = MANIPULATOR_CSS;\n shadow.appendChild(style);\n\n const handles: HTMLElement[] = [];\n for (const dir of RESIZE_DIRS) {\n const h = doc.createElement('div');\n h.className = `veo-mnp-handle veo-mnp-${dir}`;\n h.dataset.veoDir = dir;\n card.appendChild(h);\n handles.push(h);\n }\n\n let dragging = false;\n let detached = false;\n\n /** Últimos valores aplicados durante el gesto (para el commit del up). */\n let patch: DesignPatch['style'] = {};\n\n const setVars = (v: { px?: number; py?: number; w?: number; h?: number }): void => {\n const host = opts.host;\n if (v.px !== undefined) host.style.setProperty('--veo-pos-x', `${v.px * 100}%`);\n if (v.py !== undefined) host.style.setProperty('--veo-pos-y', `${v.py * 100}%`);\n if (v.w !== undefined) host.style.setProperty('--veo-width', `${v.w}px`);\n if (v.h !== undefined) host.style.setProperty('--veo-min-h', `${v.h}px`);\n };\n\n /**\n * Un gesto genérico: guarda el rect inicial, traduce cada mousemove a\n * variables CSS (rAF-throttled) y al soltar emite el commit acumulado.\n */\n const startGesture = (\n e: MouseEvent,\n apply: (dx: number, dy: number, start: DOMRect) => DesignPatch['style'],\n ): void => {\n e.preventDefault();\n e.stopPropagation();\n dragging = true;\n patch = {};\n const start = card.getBoundingClientRect();\n const sx = e.clientX;\n const sy = e.clientY;\n let raf = 0;\n let lastEv: MouseEvent | null = null;\n\n const flush = (): void => {\n raf = 0;\n if (!lastEv) return;\n const next = apply(lastEv.clientX - sx, lastEv.clientY - sy, start);\n patch = { ...patch, ...next };\n setVars({\n ...(next.posX !== undefined ? { px: next.posX } : {}),\n ...(next.posY !== undefined ? { py: next.posY } : {}),\n ...(next.width !== undefined ? { w: next.width } : {}),\n ...(next.height !== undefined ? { h: next.height } : {}),\n });\n };\n\n const move = (ev: MouseEvent): void => {\n lastEv = ev;\n // rAF-throttle del feedback; fallback síncrono si el entorno no tiene rAF.\n if (typeof window.requestAnimationFrame !== 'function') flush();\n else if (!raf) raf = window.requestAnimationFrame(flush);\n };\n const up = (): void => {\n window.removeEventListener('mousemove', move);\n window.removeEventListener('mouseup', up);\n if (raf) window.cancelAnimationFrame(raf);\n flush();\n dragging = false;\n if (Object.keys(patch).length > 0 && !detached) {\n opts.onCommit({ stepIndex: opts.stepIndex, style: patch });\n }\n opts.onGestureEnd?.();\n };\n window.addEventListener('mousemove', move);\n window.addEventListener('mouseup', up);\n };\n\n /** posX para que el borde izquierdo quede en `left` con ancho `w`. */\n const posXFor = (left: number, w: number): number => {\n const span = window.innerWidth - w;\n return span <= 0 ? 0.5 : round3(clamp(left / span, 0, 1));\n };\n const posYFor = (top: number, h: number): number => {\n const span = window.innerHeight - h;\n return span <= 0 ? 0.5 : round3(clamp(top / span, 0, 1));\n };\n\n const onCardDown = (e: MouseEvent): void => {\n if (isInteractive(e.target)) return;\n if (e.target instanceof Element && e.target.closest('.veo-mnp-handle')) return;\n startGesture(e, (dx, dy, start) => ({\n posX: posXFor(start.left + dx, start.width),\n posY: posYFor(start.top + dy, start.height),\n }));\n };\n\n const onHandleDown = (e: MouseEvent): void => {\n const dir = (e.currentTarget as HTMLElement).dataset.veoDir as ResizeDir;\n startGesture(e, (dx, dy, start) => {\n const out: DesignPatch['style'] = {};\n if (dir.includes('e')) out.width = Math.round(clamp(start.width + dx, MIN_W, MAX_W));\n if (dir.includes('w')) {\n out.width = Math.round(clamp(start.width - dx, MIN_W, MAX_W));\n // El borde derecho queda fijo: la card se re-ancla donde corresponde.\n out.posX = posXFor(start.right - out.width, out.width);\n }\n if (dir.includes('s')) out.height = Math.round(clamp(start.height + dy, MIN_H, MAX_H));\n if (dir.includes('n')) {\n out.height = Math.round(clamp(start.height - dy, MIN_H, MAX_H));\n out.posY = posYFor(start.bottom - out.height, out.height);\n }\n return out;\n });\n };\n\n card.addEventListener('mousedown', onCardDown);\n for (const h of handles) h.addEventListener('mousedown', onHandleDown);\n\n return {\n isDragging: () => dragging,\n detach: () => {\n if (detached) return;\n detached = true;\n card.removeEventListener('mousedown', onCardDown);\n for (const h of handles) h.remove();\n style.remove();\n card.classList.remove('veo-mnp-card');\n delete card.dataset.veoManipulated;\n },\n };\n}\n\n// ── Banner fijo: drag vertical con snap top/bottom ──────────────────────────\n\nfunction attachBanner(\n opts: DesignManipulatorOptions,\n shadow: ShadowRoot,\n banner: HTMLElement,\n): DesignManipulatorHandle | null {\n if (banner.dataset.veoManipulated === '1') return null;\n banner.dataset.veoManipulated = '1';\n banner.classList.add('veo-mnp-banner');\n\n const doc = banner.ownerDocument;\n const style = doc.createElement('style');\n style.textContent = MANIPULATOR_CSS;\n shadow.appendChild(style);\n\n let dragging = false;\n let detached = false;\n\n const positionOf = (): 'top' | 'bottom' =>\n banner.classList.contains('veo-banner-bottom') ? 'bottom' : 'top';\n\n const onDown = (e: MouseEvent): void => {\n if (isInteractive(e.target)) return;\n e.preventDefault();\n dragging = true;\n const startPos = positionOf();\n let current = startPos;\n\n const move = (ev: MouseEvent): void => {\n // Snap: la mitad del viewport decide top/bottom, con feedback en vivo.\n const next = ev.clientY < window.innerHeight / 2 ? 'top' : 'bottom';\n if (next !== current) {\n current = next;\n banner.classList.remove('veo-banner-top', 'veo-banner-bottom');\n banner.classList.add(`veo-banner-${next}`);\n }\n };\n const up = (): void => {\n window.removeEventListener('mousemove', move);\n window.removeEventListener('mouseup', up);\n dragging = false;\n if (current !== startPos && !detached) {\n opts.onCommit({ stepIndex: opts.stepIndex, style: { position: current } });\n }\n opts.onGestureEnd?.();\n };\n window.addEventListener('mousemove', move);\n window.addEventListener('mouseup', up);\n };\n\n banner.addEventListener('mousedown', onDown);\n\n return {\n isDragging: () => dragging,\n detach: () => {\n if (detached) return;\n detached = true;\n banner.removeEventListener('mousedown', onDown);\n style.remove();\n banner.classList.remove('veo-mnp-banner');\n delete banner.dataset.veoManipulated;\n },\n };\n}\n","/**\n * Element picker — el \"inspeccionar\" del navegador, pero del SDK. Corre\n * DENTRO de la app del cliente (no en el dashboard: son orígenes distintos\n * y el dashboard no puede leer el DOM de la app). Resalta el elemento bajo\n * el cursor, muestra su selector + dimensiones, y al hacer click captura un\n * selector CSS estable reutilizando `buildSelectorPath` del autocapture.\n *\n * Es la base del builder no-code: el dashboard abre la app del cliente en\n * modo builder, el usuario \"pincha\" un elemento y el selector resultante se\n * usa como ancla de un tooltip/walkthrough. El puente con el dashboard\n * (postMessage) es la fase siguiente; aquí exponemos el primitivo\n * `startElementPicker(onPick)`.\n *\n * No usa `innerHTML` — todo por `textContent`/DOM, igual que los renderers.\n */\n\nimport { hasDocument } from '../../utils/safe-env';\nimport { buildSelectorPath, filterHumanClasses } from '../autocapture/selector-builder';\n\n/** z-index por encima de las guías (2147483640) para tapar también una preview. */\nconst PICKER_Z = 2147483646;\nconst PICKER_HOST_ATTR = 'data-veo-picker';\nconst DEFAULT_MAX_ANCESTORS = 5;\n\n/** Datos del elemento elegido que se entregan al caller. */\nexport interface PickedElement {\n /** Selector CSS estable con ancestros (lo que se guarda como ancla). */\n selector: string;\n /** Selector corto solo del elemento (tag + id/atributo/clases). */\n shortSelector: string;\n tag: string;\n id: string | null;\n classes: string[];\n text: string;\n rect: { x: number; y: number; width: number; height: number };\n}\n\nexport interface ElementPickerOptions {\n /** Llamado al hacer click en un elemento. El picker se cierra tras esto. */\n onPick: (picked: PickedElement) => void;\n /** Llamado al cancelar (Esc). El picker se cierra. */\n onCancel?: () => void;\n /** Niveles de ancestros del selector. Default 5 (igual que autocapture). */\n maxAncestors?: number;\n /** Texto del banner superior. Default en español. */\n hint?: string;\n}\n\nexport interface ElementPickerHandle {\n /** Cierra el picker sin elegir nada. Idempotente. */\n stop(): void;\n}\n\nconst PICKER_STYLES = `\n:host { all: initial; }\n.veo-pick-box {\n position: fixed;\n z-index: ${PICKER_Z};\n pointer-events: none;\n box-sizing: border-box;\n background: rgba(99, 102, 241, 0.22);\n border: 1px dashed rgba(99, 102, 241, 0.95);\n border-radius: 2px;\n transition: top 60ms ease-out, left 60ms ease-out, width 60ms ease-out, height 60ms ease-out;\n}\n.veo-pick-label {\n position: fixed;\n z-index: ${PICKER_Z};\n pointer-events: none;\n max-width: 360px;\n background: #1e1b4b;\n color: #e0e7ff;\n font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, monospace;\n padding: 6px 9px;\n border-radius: 6px;\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);\n}\n.veo-pick-label .veo-pick-sel { color: #c7d2fe; word-break: break-all; }\n.veo-pick-label .veo-pick-dim { color: #a5b4fc; margin-top: 3px; }\n.veo-pick-hint {\n position: fixed;\n top: 12px;\n left: 50%;\n transform: translateX(-50%);\n z-index: ${PICKER_Z};\n pointer-events: none;\n background: #4338ca;\n color: #fff;\n font: 13px/1 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n padding: 8px 14px;\n border-radius: 999px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);\n}\n`;\n\n/**\n * Controla un picker activo. Singleton a nivel de módulo: empezar otro\n * cierra el anterior. Los listeners van en fase de captura para poder\n * cancelar el click ANTES de que la app del cliente reaccione.\n */\nclass ElementPicker {\n private host: HTMLElement | null = null;\n private box: HTMLElement | null = null;\n private label: HTMLElement | null = null;\n private current: Element | null = null;\n private maxAncestors = DEFAULT_MAX_ANCESTORS;\n private onPick: ((p: PickedElement) => void) | null = null;\n private onCancel: (() => void) | null = null;\n\n start(options: ElementPickerOptions): void {\n this.stop(); // solo un picker a la vez\n\n this.maxAncestors = options.maxAncestors ?? DEFAULT_MAX_ANCESTORS;\n this.onPick = options.onPick;\n this.onCancel = options.onCancel ?? null;\n\n const host = document.createElement('div');\n host.setAttribute(PICKER_HOST_ATTR, '');\n const shadow = host.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = PICKER_STYLES;\n\n this.box = document.createElement('div');\n this.box.className = 'veo-pick-box';\n this.box.style.display = 'none';\n\n this.label = document.createElement('div');\n this.label.className = 'veo-pick-label';\n this.label.style.display = 'none';\n\n const hint = document.createElement('div');\n hint.className = 'veo-pick-hint';\n hint.textContent = options.hint ?? 'Selecciona un elemento · Esc para cancelar';\n\n shadow.append(style, this.box, this.label, hint);\n document.body.appendChild(host);\n this.host = host;\n\n document.addEventListener('mousemove', this.onMove, true);\n document.addEventListener('click', this.onClick, true);\n document.addEventListener('mousedown', this.swallow, true);\n document.addEventListener('mouseup', this.swallow, true);\n document.addEventListener('keydown', this.onKey, true);\n window.addEventListener('scroll', this.reposition, true);\n window.addEventListener('resize', this.reposition);\n }\n\n stop(): void {\n document.removeEventListener('mousemove', this.onMove, true);\n document.removeEventListener('click', this.onClick, true);\n document.removeEventListener('mousedown', this.swallow, true);\n document.removeEventListener('mouseup', this.swallow, true);\n document.removeEventListener('keydown', this.onKey, true);\n window.removeEventListener('scroll', this.reposition, true);\n window.removeEventListener('resize', this.reposition);\n\n if (this.host?.parentNode) this.host.parentNode.removeChild(this.host);\n this.host = null;\n this.box = null;\n this.label = null;\n this.current = null;\n this.onPick = null;\n this.onCancel = null;\n }\n\n /** ¿Es un nodo de nuestro propio overlay? (no debe ser seleccionable). */\n private isOwn(target: EventTarget | null): boolean {\n return target instanceof Node && this.host !== null && this.host.contains(target);\n }\n\n private onMove = (event: MouseEvent): void => {\n const target = event.target;\n if (!(target instanceof Element) || this.isOwn(target)) return;\n this.current = target;\n this.draw(target);\n };\n\n private onClick = (event: MouseEvent): void => {\n const target = this.current ?? (event.target instanceof Element ? event.target : null);\n if (!target || this.isOwn(target)) return;\n\n // Evitar que la app reaccione al click de selección.\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n\n const picked = this.describe(target);\n const cb = this.onPick;\n this.stop();\n cb?.(picked);\n };\n\n private onKey = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return;\n event.preventDefault();\n event.stopPropagation();\n const cb = this.onCancel;\n this.stop();\n cb?.();\n };\n\n /** Traga mousedown/mouseup durante el picking (evita focus/active de la app). */\n private swallow = (event: MouseEvent): void => {\n if (this.isOwn(event.target)) return;\n event.preventDefault();\n event.stopPropagation();\n };\n\n private reposition = (): void => {\n if (this.current) this.draw(this.current);\n };\n\n /** Dibuja el recuadro de resalte y la etiqueta sobre el elemento dado. */\n private draw(element: Element): void {\n if (!this.box || !this.label) return;\n const rect = element.getBoundingClientRect();\n\n this.box.style.display = 'block';\n this.box.style.top = `${rect.top}px`;\n this.box.style.left = `${rect.left}px`;\n this.box.style.width = `${rect.width}px`;\n this.box.style.height = `${rect.height}px`;\n\n const shortSel = buildSelectorPath(element, 0);\n this.label.textContent = '';\n const sel = document.createElement('div');\n sel.className = 'veo-pick-sel';\n sel.textContent = shortSel;\n const dim = document.createElement('div');\n dim.className = 'veo-pick-dim';\n dim.textContent = `${Math.round(rect.width)} × ${Math.round(rect.height)}`;\n this.label.append(sel, dim);\n\n // Etiqueta debajo del recuadro; si no hay espacio, arriba.\n this.label.style.display = 'block';\n const LABEL_H = 48;\n const placeAbove = rect.bottom + 8 + LABEL_H > window.innerHeight;\n this.label.style.top = placeAbove\n ? `${Math.max(8, rect.top - LABEL_H - 8)}px`\n : `${rect.bottom + 8}px`;\n this.label.style.left = `${Math.max(8, rect.left)}px`;\n }\n\n private describe(element: Element): PickedElement {\n const rect = element.getBoundingClientRect();\n return {\n selector: buildSelectorPath(element, this.maxAncestors),\n shortSelector: buildSelectorPath(element, 0),\n tag: element.tagName.toLowerCase(),\n id: element.id || null,\n classes: filterHumanClasses(element),\n text: (element.textContent ?? '').trim().slice(0, 120),\n rect: {\n x: Math.round(rect.left),\n y: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n },\n };\n }\n}\n\nlet activePicker: ElementPicker | null = null;\n\n/**\n * Inicia el modo de selección de elementos (inspector). Resalta lo que está\n * bajo el cursor y, al hacer click, entrega un selector CSS estable.\n * Devuelve un handle con `stop()`. Iniciar otro picker cierra el anterior.\n *\n * @example\n * ```ts\n * import { startElementPicker } from '@veo/sdk';\n *\n * const picker = startElementPicker({\n * onPick: ({ selector }) => console.log('elegido:', selector),\n * onCancel: () => console.log('cancelado'),\n * });\n * // picker.stop() para abortar manualmente.\n * ```\n */\nexport function startElementPicker(options: ElementPickerOptions): ElementPickerHandle {\n if (!hasDocument()) {\n return { stop: () => {} };\n }\n if (!activePicker) activePicker = new ElementPicker();\n activePicker.start(options);\n return { stop: () => activePicker?.stop() };\n}\n\n/** Cierra el picker activo, si lo hay. Idempotente. */\nexport function stopElementPicker(): void {\n activePicker?.stop();\n}\n","/**\n * Lado APP del puente builder. Corre dentro de la app del cliente (vía\n * veo-builder.js). Si el contexto trae `?veoBuilder=<token>`, se conecta con el\n * editor de Veo, atiende comandos y devuelve el elemento elegido.\n *\n * Dos transportes:\n * - **iframe/popup** (`resolveTarget` = opener/parent): el dashboard es la\n * ventana principal y embebe/abre la app; le hablamos a esa ventana.\n * - **panel inyectado** (`ctx.panel`): la app es top-level (login real) y NOSOTROS\n * inyectamos el panel del editor encima (iframe al dashboard); le hablamos a\n * ese iframe. Es el modo sin adaptación por app.\n *\n * Seguridad: solo acepta mensajes cuyo `origin` coincida con el del dashboard\n * (`veoBuilderOrigin` / `document.referrer`) y cuyo `token` coincida.\n */\nimport {\n type BuilderClientContext,\n clearBuilderToken,\n resolveBuilderContext,\n} from '../../core/builder-token';\nimport { hasDocument, hasWindow } from '../../utils/safe-env';\nimport { closeGuidePreview, previewGuide } from '../guides/guide-preview';\nimport { attachBlockDropTarget, type BlockDropTargetHandle } from './block-drop-target';\nimport { type BuilderCommand, type BuilderEvent, VEO_BUILDER_SOURCE } from './bridge-protocol';\nimport { type BuilderPanelHandle, injectBuilderPanel } from './builder-panel';\nimport { attachDesignManipulator, type DesignManipulatorHandle } from './design-manipulator';\nimport { type ElementPickerHandle, startElementPicker } from './element-picker';\n\nexport interface BuilderModeHandle {\n /** Desconecta el puente y limpia picker/preview/panel. */\n teardown(): void;\n}\n\n/**\n * Inicializa el modo builder si hay contexto (URL o persistido). Devuelve un\n * handle, o `null` si no estamos en modo builder o no hay canal con el editor.\n * Es seguro llamarla siempre.\n */\nexport function initBuilderMode(): BuilderModeHandle | null {\n if (!hasWindow() || !hasDocument()) return null;\n\n // Contexto de la URL o de sessionStorage: sobrevive al redirect del guard de\n // auth (que suele tirar el query string) y a un login en la misma pestaña.\n const ctx = resolveBuilderContext();\n if (!ctx) return null;\n\n const token = ctx.token;\n const dashboardOrigin = resolveDashboardOrigin(ctx.origin);\n if (!dashboardOrigin) return null;\n\n let picker: ElementPickerHandle | null = null;\n let panel: BuilderPanelHandle | null = null;\n let staticTarget: Window | null = null;\n let manipulator: DesignManipulatorHandle | null = null;\n let dropTarget: BlockDropTargetHandle | null = null;\n /** Fantasma que sigue el cursor durante el drag de un bloque de la paleta. */\n let dragGhost: HTMLElement | null = null;\n /** Paso mostrado por la preview activa (destino de los drops de bloque). */\n let previewStepIndex = 0;\n /** Preview que llegó DURANTE un drag: se aplica al terminar el gesto. */\n let pendingPreview: Extract<BuilderCommand, { type: 'preview' }> | null = null;\n const getTarget = (): Window | null => (panel ? panel.target() : staticTarget);\n\n const post = (event: BuilderEvent): void => {\n getTarget()?.postMessage({ source: VEO_BUILDER_SOURCE, token, ...event }, dashboardOrigin);\n };\n\n const applyPreview = (cmd: Extract<BuilderCommand, { type: 'preview' }>): void => {\n manipulator?.detach();\n manipulator = null;\n dropTarget?.detach();\n dropTarget = null;\n previewStepIndex = cmd.guide.startStepIndex ?? 0;\n // `editorPreview: true` → los bloques de código host NO se inyectan en esta\n // página (la del editor); muestran placeholder para no corromper el editor.\n const handle = previewGuide({ ...cmd.guide, editorPreview: true });\n if (!cmd.editable) return;\n void handle.ready.then((result) => {\n if (!result.rendered) return;\n const host = handle.host();\n if (!host) return;\n manipulator = attachDesignManipulator({\n host,\n guideType: cmd.guide.guideType,\n stepIndex: cmd.guide.startStepIndex ?? 0,\n onCommit: (payload) => post({ type: 'design-updated', payload }),\n onGestureEnd: () => {\n if (!pendingPreview) return;\n const queued = pendingPreview;\n pendingPreview = null;\n applyPreview(queued);\n },\n });\n // Paleta → guía: soltar un bloque del panel sobre la preview lo inserta.\n dropTarget = attachBlockDropTarget({\n host,\n stepIndex: cmd.guide.startStepIndex ?? 0,\n onDrop: (payload) => post({ type: 'block-dropped', payload }),\n });\n });\n };\n\n const hideDragGhost = (): void => {\n dragGhost?.remove();\n dragGhost = null;\n };\n\n const moveDragGhost = (x: number, y: number, label: string): void => {\n if (!dragGhost) {\n dragGhost = document.createElement('div');\n dragGhost.style.cssText =\n 'position:fixed;padding:4px 10px;border-radius:999px;background:#1c1917;color:#fff;' +\n 'font:12px/1.4 system-ui,sans-serif;box-shadow:0 4px 14px rgba(0,0,0,0.35);' +\n 'border:1px solid rgba(255,255,255,0.25);pointer-events:none;z-index:2147483647;';\n document.body.appendChild(dragGhost);\n }\n dragGhost.textContent = label;\n dragGhost.style.left = `${x + 14}px`;\n dragGhost.style.top = `${y + 12}px`;\n };\n\n /**\n * Drag de bloque por pointer: coords relativas al iframe del panel → página.\n * En pop-out no hay mapeo (otra ventana) — se ignora.\n */\n const handleBlockDrag = (cmd: Extract<BuilderCommand, { type: 'block-drag' }>): void => {\n const rect = panel?.frameRect();\n if (!rect || !dropTarget) {\n if (cmd.phase !== 'move') hideDragGhost();\n dropTarget?.cancelHover();\n return;\n }\n const x = rect.left + cmd.x;\n const y = rect.top + cmd.y;\n if (cmd.phase === 'move') {\n moveDragGhost(x, y, cmd.label || cmd.blockType);\n dropTarget.hoverAt(x, y);\n return;\n }\n hideDragGhost();\n if (cmd.phase === 'cancel') {\n dropTarget.cancelHover();\n return;\n }\n const spotAt = dropTarget.dropAt(x, y);\n if (spotAt) {\n post({\n type: 'block-dropped',\n payload: { stepIndex: previewStepIndex, blockType: cmd.blockType, ...spotAt },\n });\n }\n };\n\n const handleCommand = (cmd: BuilderCommand): void => {\n switch (cmd.type) {\n case 'panel-ready':\n // El panel cargó y ya escucha → recién ahora le mandamos `ready`.\n post({ type: 'ready' });\n break;\n case 'start-picker':\n picker?.stop();\n picker = startElementPicker({\n onPick: (payload) => {\n picker = null;\n post({ type: 'picked', payload });\n },\n onCancel: () => {\n picker = null;\n post({ type: 'pick-cancelled' });\n },\n ...(cmd.maxAncestors !== undefined ? { maxAncestors: cmd.maxAncestors } : {}),\n ...(cmd.hint !== undefined ? { hint: cmd.hint } : {}),\n });\n break;\n case 'stop-picker':\n picker?.stop();\n picker = null;\n break;\n case 'preview':\n if (!cmd.guide) break;\n // Mientras hay un drag en curso, no remontar la preview debajo del\n // mouse del autor: se encola el ÚLTIMO comando y se aplica al soltar.\n if (manipulator?.isDragging()) pendingPreview = cmd;\n else applyPreview(cmd);\n break;\n case 'block-drag':\n handleBlockDrag(cmd);\n break;\n case 'close-preview':\n manipulator?.detach();\n manipulator = null;\n dropTarget?.detach();\n dropTarget = null;\n hideDragGhost();\n pendingPreview = null;\n closeGuidePreview();\n break;\n case 'teardown':\n teardown();\n break;\n }\n };\n\n const onMessage = (event: MessageEvent): void => {\n if (event.origin !== dashboardOrigin) return;\n const data = event.data as { source?: unknown; token?: unknown } | null;\n if (!data || data.source !== VEO_BUILDER_SOURCE || data.token !== token) return;\n handleCommand(data as BuilderCommand);\n };\n\n const onPageHide = (): void => post({ type: 'closed' });\n\n const teardown = (): void => {\n window.removeEventListener('message', onMessage);\n window.removeEventListener('pagehide', onPageHide);\n picker?.stop();\n picker = null;\n manipulator?.detach();\n manipulator = null;\n dropTarget?.detach();\n dropTarget = null;\n hideDragGhost();\n pendingPreview = null;\n closeGuidePreview();\n post({ type: 'closed' }); // avisar al editor ANTES de sacar el panel\n panel?.teardown();\n panel = null;\n clearBuilderToken(); // salir del modo builder: no re-activar en la próxima carga\n };\n\n // Transporte: panel inyectado (app top-level) o iframe/popup (embebida).\n if (ctx.panel) {\n panel = injectBuilderPanel({\n dashboardOrigin,\n token,\n appOrigin: window.location.origin,\n guide: ctx.guide,\n panelPath: ctx.panelPath,\n onClose: () => teardown(),\n });\n } else {\n staticTarget = resolveTarget();\n if (!staticTarget) return null;\n }\n\n const activate = (): void => {\n window.addEventListener('message', onMessage);\n window.addEventListener('pagehide', onPageHide);\n // Panel: esperamos el `panel-ready` del iframe para postear `ready` (todavía\n // puede no tener su listener). iframe/popup: el opener ya escucha → posteamos ya.\n if (!ctx.panel) post({ type: 'ready' });\n };\n\n // Modo panel inyectado: la seguridad ya la da la sesión AUTENTICADA del\n // dashboard (el panel es un iframe del dashboard con Clerk) — el token es solo\n // correlación. Activamos directo, SIN verify: el verify contra el backend\n // podría fallar por expiración del token durante el login (que tarda), dejando\n // el panel para siempre en \"conectando…\".\n //\n // Modo iframe/popup (embebido): verificamos el token firmado antes de activar\n // (si `init()` dejó la config). Solo bloquea si el backend dice {valid:false}.\n const cfg = (window as unknown as { __veoBuilder?: { apiKey?: string; apiUrl?: string } })\n .__veoBuilder;\n if (!ctx.panel && cfg?.apiKey && cfg?.apiUrl) {\n void verifyBuilderToken(cfg.apiUrl, cfg.apiKey, token).then((ok) => {\n if (ok) activate();\n else if (window.console) console.warn('[veo] token de builder inválido — modo no activado');\n });\n } else {\n activate();\n }\n\n return { teardown };\n}\n\n/**\n * Verifica el token con el backend. Solo devuelve `false` (no activar) cuando el\n * backend responde explícitamente `{valid:false}` (token forjado/expirado/de\n * otro workspace). Ante 404/red caída/errores transitorios devuelve `true`\n * (best-effort) para no brickear el modo builder.\n */\nasync function verifyBuilderToken(apiUrl: string, apiKey: string, token: string): Promise<boolean> {\n try {\n const url = `${apiUrl.replace(/\\/+$/, '')}/v1/builder/verify`;\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': apiKey },\n body: JSON.stringify({ token }),\n });\n if (!res.ok) return true; // no pudimos verificar → best-effort\n const data = (await res.json().catch(() => null)) as { valid?: unknown } | null;\n return data?.valid !== false;\n } catch {\n return true; // red caída / sin backend → best-effort\n }\n}\n\n/** Ventana con la que hablar en modo iframe/popup: el opener o el parent. */\nfunction resolveTarget(): Window | null {\n if (window.opener && window.opener !== window) return window.opener as Window;\n if (window.parent && window.parent !== window) return window.parent;\n return null;\n}\n\nfunction resolveDashboardOrigin(originHint: string | null): string | null {\n // Origen de la URL o persistido en el primer arranque (antes del redirect).\n if (originHint) {\n try {\n return new URL(originHint).origin;\n } catch {\n return null;\n }\n }\n // Fallback: el referrer. Poco fiable tras un redirect same-origin (apunta a la\n // propia app), por eso el origen persistido va primero.\n if (hasDocument() && document.referrer) {\n try {\n return new URL(document.referrer).origin;\n } catch {\n return null;\n }\n }\n return null;\n}\n\n// Tipo re-exportado para consumidores que tipan el contexto.\nexport type { BuilderClientContext };\n","/**\n * Lado DASHBOARD del puente builder. Abre la app del cliente en un popup,\n * en modo builder, y expone una API para pedirle que seleccione un elemento\n * o previsualice una guía. Pensado para importarse en el dashboard\n * (`import { createBuilderSession } from '@veo/sdk/builder'`).\n *\n * Seguridad: solo procesa mensajes cuyo `origin` sea el de la app y cuyo\n * `token` coincida con el de esta sesión.\n */\nimport { hasWindow } from '../../utils/safe-env';\nimport type { PreviewGuideInput } from '../guides/guide-preview';\nimport {\n BUILDER_ORIGIN_PARAM,\n BUILDER_TOKEN_PARAM,\n type BuilderCommand,\n VEO_BUILDER_SOURCE,\n} from './bridge-protocol';\nimport type { PickedElement } from './element-picker';\n\nexport interface BuilderSessionOptions {\n /** URL de la app del cliente a abrir en modo builder. */\n appUrl: string;\n /** Token de la sesión (idealmente emitido/firmado por el backend). */\n token: string;\n /** Origen al que la app debe responder. Default: `location.origin`. */\n dashboardOrigin?: string;\n /** La app está lista y escuchando comandos. */\n onReady?: () => void;\n /** El usuario eligió un elemento. */\n onPicked?: (picked: PickedElement) => void;\n /** El usuario canceló la selección (Esc). */\n onCancelled?: () => void;\n /** La app cerró el modo builder (o el popup se cerró). */\n onClosed?: () => void;\n /**\n * Si se pasa, la app se embebe en este `<iframe>` (modo estudio in-app) en\n * lugar de abrirse en un popup. El lado app ya habla con `window.parent`,\n * así que el puente funciona igual. La sesión setea el `src` del iframe.\n */\n frame?: HTMLIFrameElement;\n /** Nombre de la ventana popup. Default: `veo-builder`. */\n windowName?: string;\n /** Features del popup. Default: ventana de ~1280×860. */\n windowFeatures?: string;\n}\n\nexport interface BuilderSession {\n /** Pide a la app que entre en modo selección de elemento. */\n startPicker(options?: { maxAncestors?: number; hint?: string }): void;\n /** Cancela la selección en curso. */\n stopPicker(): void;\n /** Pide a la app que previsualice una guía. */\n preview(guide: PreviewGuideInput): void;\n /** Cierra la preview activa en la app. */\n closePreview(): void;\n /** Cierra el popup y desconecta el puente. */\n close(): void;\n}\n\nconst DEFAULT_FEATURES = 'popup,width=1280,height=860';\nconst POPUP_POLL_MS = 600;\n\nexport function createBuilderSession(options: BuilderSessionOptions): BuilderSession {\n if (!hasWindow()) return noopSession();\n\n const dashboardOrigin = options.dashboardOrigin ?? window.location.origin;\n const appOrigin = safeOrigin(options.appUrl);\n const url = buildAppUrl(options.appUrl, options.token, dashboardOrigin);\n\n const frame = options.frame ?? null;\n const useFrame = frame !== null;\n\n let popup: Window | null = null;\n if (useFrame) {\n // biome-ignore lint/style/noNonNullAssertion: useFrame garantiza frame\n frame!.src = url;\n } else {\n popup = window.open(\n url,\n options.windowName ?? 'veo-builder',\n options.windowFeatures ?? DEFAULT_FEATURES,\n );\n }\n\n /** Ventana destino de los comandos: el popup o el contentWindow del iframe. */\n const targetWindow = (): Window | null => (useFrame ? (frame?.contentWindow ?? null) : popup);\n\n const post = (command: BuilderCommand): void => {\n const w = targetWindow();\n if (!w) return;\n if (!useFrame && popup?.closed) return;\n w.postMessage(\n { source: VEO_BUILDER_SOURCE, token: options.token, ...command },\n appOrigin ?? '*',\n );\n };\n\n let pollTimer: ReturnType<typeof setInterval> | undefined;\n\n const cleanup = (): void => {\n window.removeEventListener('message', onMessage);\n if (pollTimer !== undefined) {\n clearInterval(pollTimer);\n pollTimer = undefined;\n }\n };\n\n const onMessage = (event: MessageEvent): void => {\n if (appOrigin && event.origin !== appOrigin) return;\n const data = event.data as {\n source?: unknown;\n token?: unknown;\n type?: unknown;\n payload?: unknown;\n } | null;\n if (!data || data.source !== VEO_BUILDER_SOURCE || data.token !== options.token) return;\n\n switch (data.type) {\n case 'ready':\n options.onReady?.();\n break;\n case 'picked':\n if (data.payload) options.onPicked?.(data.payload as PickedElement);\n break;\n case 'pick-cancelled':\n options.onCancelled?.();\n break;\n case 'closed':\n cleanup();\n options.onClosed?.();\n break;\n }\n };\n\n window.addEventListener('message', onMessage);\n\n // Detectar cierre manual del popup (el usuario cierra la ventana). En modo\n // iframe el ciclo de vida lo controla el dashboard (no hay nada que pollear).\n if (!useFrame) {\n pollTimer = setInterval(() => {\n if (popup?.closed) {\n cleanup();\n options.onClosed?.();\n }\n }, POPUP_POLL_MS);\n }\n\n return {\n startPicker: (o) =>\n post({\n type: 'start-picker',\n ...(o?.maxAncestors !== undefined ? { maxAncestors: o.maxAncestors } : {}),\n ...(o?.hint !== undefined ? { hint: o.hint } : {}),\n }),\n stopPicker: () => post({ type: 'stop-picker' }),\n preview: (guide) => post({ type: 'preview', guide }),\n closePreview: () => post({ type: 'close-preview' }),\n close: () => {\n post({ type: 'teardown' });\n if (useFrame) {\n if (frame) frame.src = 'about:blank';\n } else if (popup && !popup.closed) {\n popup.close();\n }\n cleanup();\n },\n };\n}\n\nfunction buildAppUrl(appUrl: string, token: string, dashboardOrigin: string): string {\n try {\n const u = new URL(appUrl, window.location.href);\n u.searchParams.set(BUILDER_TOKEN_PARAM, token);\n u.searchParams.set(BUILDER_ORIGIN_PARAM, dashboardOrigin);\n return u.toString();\n } catch {\n return appUrl;\n }\n}\n\nfunction safeOrigin(url: string): string | null {\n try {\n return new URL(url, window.location.href).origin;\n } catch {\n return null;\n }\n}\n\nfunction noopSession(): BuilderSession {\n return {\n startPicker: () => {},\n stopPicker: () => {},\n preview: () => {},\n closePreview: () => {},\n close: () => {},\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/plugins/plugin.ts","../src/core/preview-loader.ts","../src/plugins/guides/preview-mode.ts","../src/plugins/guides/guide-frequency-cache.ts","../src/plugins/guides/guide-resolver-client.ts","../src/plugins/guides/guide-tracker-client.ts","../src/plugins/guides/guide-tracker-queue.ts","../src/plugins/guides/url-match.ts","../src/plugins/guides/walkthrough-state.ts","../src/plugins/guides/guides-controller.ts","../src/plugins/guides/index.ts"],"names":["renderer"],"mappings":"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","file":"chunk-6HPLYPFN.mjs","sourcesContent":["import type { VeoPlugin } from '../types';\n\n/**\n * Helper de identidad para definir un plugin con inferencia de tipos.\n * No transforma nada; mejora la ergonomía y deja un punto de extensión futuro.\n */\nexport function definePlugin(plugin: VeoPlugin): VeoPlugin {\n return plugin;\n}\n","/**\n * Detección del modo PREVIEW POR LINK (`?veoPreview=<token>`). El core solo\n * detecta el param — el canje del token y el render viven en el bundle de\n * guías (`plugins/guides/preview-mode.ts`), que el caller carga\n * (estático en `index.ts`, lazy en `veo.ts`).\n *\n * El nombre del query param es parte del contrato con el dashboard (el link\n * generado por «Previsualizar en mi app»).\n */\nimport { hasWindow } from '../utils/safe-env';\n\nexport const PREVIEW_TOKEN_PARAM = 'veoPreview';\n/**\n * El token se PERSISTE en sessionStorage: al navegar entre páginas de la app la\n * URL pierde `?veoPreview`, y sin esto el modo preview (y su chip de control) se\n * apagaba al saltar de página. sessionStorage sobrevive la navegación de la\n * pestaña y muere al cerrarla — justo el alcance de una sesión de preview.\n */\nconst PREVIEW_TOKEN_KEY = 'veo:preview_token';\n\nfunction session(): Storage | null {\n try {\n return window.sessionStorage;\n } catch {\n return null; // modo privado / sandbox: seguimos solo con la URL\n }\n}\n\n/**\n * Token del link de preview. Lo toma de la URL (`?veoPreview`) y lo persiste; si\n * la URL no lo trae (navegó a otra página), lo recupera de sessionStorage.\n * `null` si no hay ninguno. Se limpia con {@link clearPreviewToken}.\n */\nexport function getPreviewToken(): string | null {\n if (!hasWindow()) return null;\n let fromUrl: string | null = null;\n try {\n const value = new URLSearchParams(window.location.search).get(PREVIEW_TOKEN_PARAM);\n fromUrl = value ? value : null;\n } catch {\n fromUrl = null;\n }\n const store = session();\n if (fromUrl) {\n try {\n store?.setItem(PREVIEW_TOKEN_KEY, fromUrl);\n } catch {\n // no-op: sin storage seguimos con el token de la URL\n }\n return fromUrl;\n }\n try {\n return store?.getItem(PREVIEW_TOKEN_KEY) || null;\n } catch {\n return null;\n }\n}\n\n/** Sale del modo preview: borra el token persistido (lo llama el chip al cerrar). */\nexport function clearPreviewToken(): void {\n try {\n session()?.removeItem(PREVIEW_TOKEN_KEY);\n } catch {\n // no-op\n }\n}\n\n/**\n * `true` cuando la app corre en modo preview-por-link. Igual que en modo\n * builder, el runtime NO debe instalar el plugin de guías: las guías live\n * taparían/duplicarían la guía que se está previsualizando.\n */\nexport function isPreviewMode(): boolean {\n return getPreviewToken() !== null;\n}\n","/**\n * Modo PREVIEW POR LINK: la app del cliente se abre con\n * `?veoPreview=<token>` (link generado desde el dashboard) y el SDK canjea\n * el token contra `POST /v1/guides/preview-resolve` para renderizar ESA\n * guía como vista previa — aunque esté en draft — sobre la app real.\n *\n * A diferencia del modo builder no hay puente postMessage ni dashboard\n * abierto: es un link compartible para que el equipo pruebe la guía sin\n * publicarla. Reusa `previewGuide` (sin tracking/frecuencia/resolver) y\n * monta un chip flotante con \"volver a mostrar\" y \"cerrar\".\n *\n * Vive en el bundle de guías (`veo-guides.js`), NO en el `veo.js` core —\n * el core solo detecta el query param y dispara la carga del bundle.\n */\nimport { clearPreviewToken } from '../../core/preview-loader';\nimport { hasDocument } from '../../utils/safe-env';\nimport { previewGuide } from './guide-preview';\nimport type { ResolvedGuide } from './types';\n\nexport interface PreviewModeOptions {\n apiKey: string;\n apiUrl: string;\n /** Token firmado del link (`?veoPreview=<token>`). */\n token: string;\n debug?: boolean;\n}\n\nexport interface PreviewModeHandle {\n /** Cierra la preview y quita el chip. Idempotente. */\n teardown(): void;\n}\n\nlet active: PreviewModeHandle | null = null;\n\n/**\n * Canjea el token y renderiza la guía como vista previa + chip de control.\n * Si el token es inválido/expirado, el chip lo informa (solo quien tiene el\n * link lo ve). Solo una sesión de preview activa a la vez.\n */\nexport async function runPreviewMode(opts: PreviewModeOptions): Promise<PreviewModeHandle | null> {\n if (!hasDocument()) return null;\n active?.teardown();\n\n let guide: ResolvedGuide | null = null;\n try {\n const res = await fetch(`${opts.apiUrl}/v1/guides/preview-resolve`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': opts.apiKey },\n body: JSON.stringify({ token: opts.token }),\n });\n if (res.ok) {\n const data = (await res.json()) as { guide?: ResolvedGuide };\n guide = data.guide ?? null;\n } else if (opts.debug) {\n console.warn('[veo] preview-resolve respondió', res.status);\n }\n } catch (err) {\n if (opts.debug) console.warn('[veo] preview-resolve falló:', err);\n }\n\n /**\n * En el link de preview el envío de forms es REAL: corre sobre la app del\n * cliente con el SDK inicializado, así que la respuesta se guarda en el\n * usuario que está probando (su propia identidad) — permite verificar el\n * flujo completo props→segmentos sin tocar a nadie más.\n */\n const submitToBackend = async (answers: Record<string, unknown>): Promise<boolean> => {\n if (!guide) return false;\n const veo = (\n window as unknown as {\n veo?: { getEndUserId?: () => string | null; getAnonymousId?: () => string };\n }\n ).veo;\n const endUserId = veo?.getEndUserId?.() ?? veo?.getAnonymousId?.() ?? null;\n if (!endUserId) return false;\n try {\n const res = await fetch(`${opts.apiUrl}/v1/guides/${guide.guideId}/form-response`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': opts.apiKey },\n body: JSON.stringify({ endUserId, answers }),\n });\n return res.ok;\n } catch {\n return false;\n }\n };\n\n let preview: { close(): void } | null = null;\n const show = (): void => {\n if (!guide) return;\n preview?.close();\n preview = previewGuide({\n guideType: guide.guideType,\n guideSteps: guide.guideSteps,\n activationRules: guide.activationRules,\n guideName: guide.guideName,\n formSubmit: submitToBackend,\n formSubmitNote: 'Vista previa: guardado en TU usuario para probar el flujo.',\n });\n };\n\n const chip = mountChip({\n label: guide ? `Vista previa: ${guide.guideName}` : 'Link de preview inválido o vencido',\n error: !guide,\n onReshow: guide ? show : null,\n onClose: () => handle.teardown(),\n });\n\n const handle: PreviewModeHandle = {\n teardown() {\n preview?.close();\n preview = null;\n chip.remove();\n // Salir de verdad: borra el token persistido para que NO reaparezca al\n // navegar (si no, sessionStorage lo reviviría en la próxima página).\n clearPreviewToken();\n if (active === handle) active = null;\n },\n };\n active = handle;\n show();\n return handle;\n}\n\ninterface ChipOptions {\n label: string;\n error: boolean;\n onReshow: (() => void) | null;\n onClose: () => void;\n}\n\n/** Chip flotante (Shadow DOM, abajo-derecha) con re-mostrar y cerrar. */\nfunction mountChip(opts: ChipOptions): { remove(): void } {\n const host = document.createElement('div');\n host.setAttribute('data-veo-preview-chip', '');\n const root = host.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = `\n .chip { position: fixed; bottom: 16px; right: 16px; z-index: 2147483647;\n display: flex; align-items: center; gap: 8px; padding: 8px 12px;\n background: #111827; color: #f9fafb; border-radius: 9999px;\n font: 500 12px/1.2 system-ui, sans-serif; box-shadow: 0 4px 12px rgba(0,0,0,.25); }\n .chip.error { background: #7f1d1d; }\n .label { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n button { all: unset; cursor: pointer; padding: 2px 6px; border-radius: 9999px;\n font-size: 12px; line-height: 1; }\n button:hover { background: rgba(255,255,255,.15); }\n `;\n root.appendChild(style);\n\n const chip = document.createElement('div');\n chip.className = opts.error ? 'chip error' : 'chip';\n\n const label = document.createElement('span');\n label.className = 'label';\n label.textContent = opts.label;\n chip.appendChild(label);\n\n if (opts.onReshow) {\n const reshow = document.createElement('button');\n reshow.textContent = '↻';\n reshow.title = 'Volver a mostrar la guía';\n reshow.addEventListener('click', opts.onReshow);\n chip.appendChild(reshow);\n }\n\n const close = document.createElement('button');\n close.textContent = '✕';\n close.title = 'Salir de la vista previa';\n close.addEventListener('click', opts.onClose);\n chip.appendChild(close);\n\n root.appendChild(chip);\n document.body.appendChild(host);\n return { remove: () => host.remove() };\n}\n","import {\n FREQUENCY_CACHE_KEY_PREFIX,\n FREQUENCY_CACHE_MAX_ENTRIES,\n FREQUENCY_CACHE_TTL_MS,\n} from './constants';\nimport type { DisplayFrequency, FrequencyCacheEntry, FrequencyStatus } from './types';\n\n/** Prioridad de status para no degradar shown→dismissed→… */\nconst STATUS_PRIORITY: Record<FrequencyStatus, number> = {\n shown: 1,\n dismissed: 2,\n completed: 2,\n};\n\n/**\n * Namespace short y estable derivado del apiKey. NO es cripto: solo evita\n * que dos apps que comparten el navegador pisen sus caches. El apiKey\n * público (`pk_*`) ya es workspace-único, así que usar sus últimos 16\n * caracteres alcanza para diferenciar.\n */\nexport function namespaceFromApiKey(apiKey: string): string {\n return apiKey.slice(-16) || 'default';\n}\n\n/**\n * Cache persistente de \"qué guías ya vio/cerró este usuario\". Vive en\n * `localStorage` con key namespaceada para evitar colisión entre\n * workspaces que corren en el mismo navegador.\n *\n * No es source of truth — el backend siempre manda. Esta cache solo\n * evita el flash visual de re-pintar una guía que el usuario ya cerró\n * antes de que el roundtrip al backend termine.\n */\nexport class GuideFrequencyCache {\n private readonly storageKey: string;\n private cache: Map<string, FrequencyCacheEntry>;\n\n constructor(namespace: string) {\n this.storageKey = `${FREQUENCY_CACHE_KEY_PREFIX}${namespace}`;\n this.cache = this.load();\n this.prune();\n }\n\n /**\n * Decide si una guía debe filtrarse localmente antes de pintarla.\n *\n * - `every_visit` / `always` → nunca filtra (siempre re-pinta).\n * - `once` → cualquier entry registrada filtra (verla ya cuenta).\n * - `until_dismissed` → si fue descartada O COMPLETADA (responder un\n * form / terminar un walkthrough es más fuerte que descartar — sin\n * esto, una encuesta seguiría preguntando después de respondida).\n */\n shouldFilter(guideId: string, displayFrequency: DisplayFrequency): boolean {\n if (displayFrequency === 'every_visit' || displayFrequency === 'always') return false;\n\n const entry = this.cache.get(guideId);\n if (!entry) return false;\n\n if (displayFrequency === 'once') return true;\n if (displayFrequency === 'until_dismissed') {\n return entry.status === 'dismissed' || entry.status === 'completed';\n }\n // `until_answered` (forms): solo COMPLETAR filtra localmente. El descarte\n // no la silencia — y si las props ya tienen valor por otro medio, es el\n // BACKEND quien la excluye del resolve (aquí no conocemos los traits).\n if (displayFrequency === 'until_answered') return entry.status === 'completed';\n return false;\n }\n\n /**\n * Registra/actualiza la entry de una guía. Nunca degrada un estado más\n * fuerte (no convierte `dismissed` en `shown` por un re-render). Persiste\n * cada llamada — escribir a localStorage es lo bastante barato.\n */\n record(guideId: string, status: FrequencyStatus): void {\n const existing = this.cache.get(guideId);\n if (existing && STATUS_PRIORITY[status] < STATUS_PRIORITY[existing.status]) {\n return;\n }\n this.cache.set(guideId, {\n guideId,\n status,\n lastInteractionAt: Date.now(),\n });\n this.persist();\n }\n\n /** Limpia el cache (botón \"reset\" del demo, tests). */\n clear(): void {\n this.cache.clear();\n this.persist();\n }\n\n /** Útil para debugging — devuelve un snapshot. */\n snapshot(): FrequencyCacheEntry[] {\n return Array.from(this.cache.values());\n }\n\n /**\n * Limpia entries expiradas por TTL y, si aún excede el límite, descarta\n * las más viejas hasta caber. Se ejecuta una vez en el constructor; no\n * vale la pena correrlo a cada lectura.\n */\n private prune(): void {\n const now = Date.now();\n let mutated = false;\n\n for (const [id, entry] of this.cache) {\n if (now - entry.lastInteractionAt > FREQUENCY_CACHE_TTL_MS) {\n this.cache.delete(id);\n mutated = true;\n }\n }\n\n if (this.cache.size > FREQUENCY_CACHE_MAX_ENTRIES) {\n const sorted = Array.from(this.cache.entries()).sort(\n (a, b) => a[1].lastInteractionAt - b[1].lastInteractionAt,\n );\n const excess = this.cache.size - FREQUENCY_CACHE_MAX_ENTRIES;\n for (let i = 0; i < excess; i++) {\n const tuple = sorted[i];\n if (tuple) this.cache.delete(tuple[0]);\n }\n mutated = true;\n }\n\n if (mutated) this.persist();\n }\n\n private load(): Map<string, FrequencyCacheEntry> {\n if (typeof localStorage === 'undefined') return new Map();\n try {\n const raw = localStorage.getItem(this.storageKey);\n if (!raw) return new Map();\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed)) return new Map();\n const entries: Array<[string, FrequencyCacheEntry]> = [];\n for (const item of parsed) {\n if (\n item &&\n typeof item === 'object' &&\n typeof (item as FrequencyCacheEntry).guideId === 'string' &&\n typeof (item as FrequencyCacheEntry).lastInteractionAt === 'number' &&\n ['shown', 'dismissed', 'completed'].includes((item as FrequencyCacheEntry).status)\n ) {\n const e = item as FrequencyCacheEntry;\n entries.push([e.guideId, e]);\n }\n }\n return new Map(entries);\n } catch {\n return new Map();\n }\n }\n\n private persist(): void {\n if (typeof localStorage === 'undefined') return;\n try {\n const serialized = JSON.stringify(Array.from(this.cache.values()));\n localStorage.setItem(this.storageKey, serialized);\n } catch {\n // QuotaExceeded o similar — el cache es opcional, no rompemos la app.\n }\n }\n}\n","import type { ResolvedGuide, ResolveGuidesResponse } from './types';\n\n/**\n * Wrapper sobre `GET /v1/guides/resolve`. Nunca lanza: cualquier error de\n * red o de parsing devuelve un array vacío, para que el plugin no rompa\n * la app del cliente.\n *\n * Importante: el endpoint usa `?pageUrl=...` (no `?url=...`) — el backend\n * valida con class-validator `IsUrl({ require_protocol: true })`.\n */\nexport class GuideResolverClient {\n constructor(\n private readonly apiUrl: string,\n private readonly apiKey: string,\n private readonly debug = false,\n ) {}\n\n async resolve(endUserId: string, pageUrl: string): Promise<ResolvedGuide[]> {\n const params = new URLSearchParams({ endUserId, pageUrl });\n let response: Response;\n try {\n response = await fetch(`${this.apiUrl}/v1/guides/resolve?${params.toString()}`, {\n method: 'GET',\n headers: { 'X-Api-Key': this.apiKey },\n credentials: 'omit',\n });\n } catch (err) {\n if (this.debug) console.error('[veo] guides resolve fetch failed:', err);\n return [];\n }\n\n if (!response.ok) {\n if (this.debug) console.warn('[veo] guides resolve HTTP', response.status);\n return [];\n }\n\n try {\n const data = (await response.json()) as ResolveGuidesResponse;\n return Array.isArray(data.guides) ? data.guides : [];\n } catch (err) {\n if (this.debug) console.error('[veo] guides resolve parse failed:', err);\n return [];\n }\n }\n\n /**\n * Trae una guía específica por ID, sin pasar por la lógica de\n * activación. La usa el controller para resumir un walkthrough entre\n * páginas: el `resolve` no devuelve la guía si la URL actual no\n * matchea, pero el walkthrough activo debe poder consultarla igual.\n *\n * El endpoint backend (`GET /v1/guides/:guideId`) devuelve `GuideResponse`,\n * un superset de `ResolvedGuide` con campos de audit. Aquí descartamos los\n * extra y nos quedamos con el shape que el resto del SDK ya consume.\n *\n * Devuelve `null` en cualquier error (404, red, parse) — el caller debe\n * tratarlo como \"guía ya no existe\" y cancelar el walkthrough limpiamente.\n */\n async fetchById(guideId: string): Promise<ResolvedGuide | null> {\n let response: Response;\n try {\n response = await fetch(`${this.apiUrl}/v1/guides/${encodeURIComponent(guideId)}`, {\n method: 'GET',\n headers: { 'X-Api-Key': this.apiKey },\n credentials: 'omit',\n });\n } catch (err) {\n if (this.debug) console.error('[veo] guides fetchById network failed:', err);\n return null;\n }\n\n if (!response.ok) {\n if (this.debug) console.warn('[veo] guides fetchById HTTP', response.status);\n return null;\n }\n\n try {\n const data = (await response.json()) as Partial<ResolvedGuide>;\n if (\n typeof data.guideId !== 'string' ||\n typeof data.guideName !== 'string' ||\n typeof data.guideType !== 'string' ||\n !Array.isArray(data.guideSteps) ||\n !data.activationRules ||\n typeof data.displayFrequency !== 'string' ||\n typeof data.displayPriority !== 'number'\n ) {\n if (this.debug) console.warn('[veo] guides fetchById: unexpected shape');\n return null;\n }\n return {\n guideId: data.guideId,\n guideName: data.guideName,\n guideType: data.guideType,\n guideSteps: data.guideSteps,\n activationRules: data.activationRules,\n displayFrequency: data.displayFrequency,\n displayPriority: data.displayPriority,\n };\n } catch (err) {\n if (this.debug) console.error('[veo] guides fetchById parse failed:', err);\n return null;\n }\n }\n}\n","import type { GuideInteractionMetadata, GuideInteractionPayload } from './types';\n\nexport interface InteractionRequest {\n guideId: string;\n payload: GuideInteractionPayload;\n}\n\n/**\n * Wire shape esperada por `POST /v1/guides/:id/interactions` en el backend.\n * Nuestro tipo interno (`GuideInteractionPayload`) usa `action`/`stepIndex`;\n * el backend exige `interactionType`/`stepPosition`. Esta función centraliza\n * la traducción.\n */\ninterface WireInteraction {\n endUserId: string;\n sessionId?: string;\n interactionType: GuideInteractionPayload['action'];\n stepPosition?: number;\n pageUrl?: string;\n pagePath?: string;\n metadata?: GuideInteractionMetadata;\n}\n\nfunction toWire(payload: GuideInteractionPayload): WireInteraction {\n const wire: WireInteraction = {\n endUserId: payload.endUserId,\n interactionType: payload.action,\n };\n if (payload.sessionId) wire.sessionId = payload.sessionId;\n if (typeof payload.stepIndex === 'number') wire.stepPosition = payload.stepIndex;\n if (payload.pageUrl) wire.pageUrl = payload.pageUrl;\n if (payload.pagePath) wire.pagePath = payload.pagePath;\n if (payload.metadata) wire.metadata = payload.metadata;\n return wire;\n}\n\n/**\n * Cliente HTTP puro para registrar interacciones de guías. No hace retry\n * ni queue — esa responsabilidad vive en `GuideTrackerQueue`.\n *\n * `send` lanza en error (queue puede reintentar). `sendBeacon` es síncrono,\n * \"best effort\", para el cierre de página: usa `navigator.sendBeacon` con\n * el apiKey como query param `?key=` (la única forma de autenticar con\n * sendBeacon, ya que no permite headers custom — el backend lo soporta\n * desde el ApiKeyGuard).\n */\nexport class GuideTrackerClient {\n constructor(\n private readonly apiUrl: string,\n private readonly apiKey: string,\n ) {}\n\n async send(request: InteractionRequest): Promise<void> {\n const url = this.buildUrl(request.guideId);\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'X-Api-Key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(toWire(request.payload)),\n credentials: 'omit',\n });\n\n if (!response.ok) {\n throw new Error(`guide interaction send failed: HTTP ${response.status}`);\n }\n }\n\n /**\n * Envío \"fire-and-forget\" en pagehide. Devuelve `false` si el navegador\n * no acepta el beacon (cola llena, no soportado) — en ese caso la queue\n * sabrá que perdió el envío.\n */\n sendBeacon(request: InteractionRequest): boolean {\n if (typeof navigator === 'undefined' || typeof navigator.sendBeacon !== 'function') {\n return false;\n }\n const url = `${this.buildUrl(request.guideId)}?key=${encodeURIComponent(this.apiKey)}`;\n const blob = new Blob([JSON.stringify(toWire(request.payload))], {\n type: 'application/json',\n });\n try {\n return navigator.sendBeacon(url, blob);\n } catch {\n return false;\n }\n }\n\n private buildUrl(guideId: string): string {\n return `${this.apiUrl}/v1/guides/${encodeURIComponent(guideId)}/interactions`;\n }\n}\n","import type { GuideTrackerClient, InteractionRequest } from './guide-tracker-client';\nimport type { QueuedInteraction } from './types';\n\n/** Base del backoff de reintento (ms); crece exponencial hasta el tope. */\nconst RETRY_BASE_MS = 3000;\nconst RETRY_MAX_DELAY_MS = 30_000;\n\nexport interface GuideTrackerQueueConfig {\n client: GuideTrackerClient;\n flushIntervalMs: number;\n batchSize: number;\n maxRetries: number;\n /**\n * Llamado cuando un item se descarta tras agotar `maxRetries`. El\n * plugin puede usarlo para `console.warn` en debug mode. Nunca debe\n * lanzar — si lo hace, se ignora silenciosamente.\n */\n onError?: (error: Error, item: QueuedInteraction) => void;\n}\n\n/**\n * Queue dedicada para `POST /v1/guides/:id/interactions`.\n *\n * Cada item es independiente (URL distinto por `guideId`), así que el\n * \"batch\" en realidad dispara N requests en paralelo. El `batchSize` es\n * el umbral para forzar un flush — no agrupa requests en uno solo.\n *\n * Retry:\n * - Si `send()` lanza, el item se devuelve al buffer con `attempts++`.\n * - El timer regular vuelve a intentar en el próximo tick.\n * - Al alcanzar `maxRetries`, se descarta llamando `onError`.\n *\n * En `pagehide`/`visibilitychange` (hidden) drena el buffer vía\n * `navigator.sendBeacon`. Best effort — no re-encola lo que el beacon\n * rechace porque la página ya se va.\n */\nexport class GuideTrackerQueue {\n private buffer: QueuedInteraction[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n private unloadCleanup: (() => void) | null = null;\n\n constructor(private readonly config: GuideTrackerQueueConfig) {\n this.startTimer();\n this.installUnloadHandler();\n }\n\n /** Tamaño actual del buffer (útil para debug/stats en el demo). */\n get size(): number {\n return this.buffer.length;\n }\n\n /**\n * Encola una interaction. Si el buffer alcanza `batchSize`, dispara\n * `flush()` inmediato.\n */\n enqueue(request: InteractionRequest): void {\n this.buffer.push({\n guideId: request.guideId,\n payload: request.payload,\n attempts: 0,\n enqueuedAt: Date.now(),\n });\n if (this.buffer.length >= this.config.batchSize) {\n void this.flush();\n }\n }\n\n /**\n * Envía todo el buffer en paralelo. Items que fallan vuelven al buffer\n * si todavía tienen reintentos disponibles. Idempotente con respecto a\n * flushes concurrentes (el segundo es un no-op).\n */\n async flush(): Promise<void> {\n if (this.flushing || this.buffer.length === 0) return;\n\n // Solo enviamos los items VENCIDOS (nextRetryAt en el pasado). Los que\n // esperan su backoff+jitter tras un fallo quedan en el buffer para un\n // tick futuro — así los reintentos de distintos clientes no se sincronizan.\n const now = Date.now();\n const due = this.buffer.filter((item) => (item.nextRetryAt ?? 0) <= now);\n if (due.length === 0) return;\n this.flushing = true;\n\n const dueSet = new Set(due);\n this.buffer = this.buffer.filter((item) => !dueSet.has(item));\n\n const results = await Promise.allSettled(\n due.map((item) => this.config.client.send({ guideId: item.guideId, payload: item.payload })),\n );\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n const item = due[i];\n if (!result || !item) continue;\n if (result.status === 'fulfilled') continue;\n\n item.attempts += 1;\n if (item.attempts < this.config.maxRetries) {\n item.nextRetryAt = Date.now() + this.retryDelayMs(item.attempts);\n this.buffer.push(item);\n } else {\n this.safeOnError(result.reason, item);\n }\n }\n\n this.flushing = false;\n }\n\n /**\n * Backoff exponencial (base = intervalo de flush) con equal-jitter: mitad\n * fija + mitad aleatoria. Desincroniza los reintentos entre clientes ante\n * una caída del backend.\n */\n private retryDelayMs(attempts: number): number {\n const base = Math.min(RETRY_BASE_MS * 2 ** (attempts - 1), RETRY_MAX_DELAY_MS);\n return base / 2 + Math.random() * (base / 2);\n }\n\n /**\n * Drena el buffer vía `sendBeacon`. Síncrono, sin retry. Para pagehide.\n */\n flushBeacon(): void {\n if (this.buffer.length === 0) return;\n const batch = this.buffer.splice(0, this.buffer.length);\n for (const item of batch) {\n this.config.client.sendBeacon({ guideId: item.guideId, payload: item.payload });\n }\n }\n\n destroy(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n this.unloadCleanup?.();\n this.unloadCleanup = null;\n }\n\n private startTimer(): void {\n if (typeof window === 'undefined') return;\n this.timer = setInterval(() => {\n void this.flush();\n }, this.config.flushIntervalMs);\n }\n\n private installUnloadHandler(): void {\n if (typeof window === 'undefined') return;\n const onPagehide = (): void => this.flushBeacon();\n const onVisibility = (): void => {\n if (document.visibilityState === 'hidden') this.flushBeacon();\n };\n window.addEventListener('pagehide', onPagehide);\n window.addEventListener('visibilitychange', onVisibility);\n this.unloadCleanup = () => {\n window.removeEventListener('pagehide', onPagehide);\n window.removeEventListener('visibilitychange', onVisibility);\n };\n }\n\n private safeOnError(reason: unknown, item: QueuedInteraction): void {\n if (!this.config.onError) return;\n const error = reason instanceof Error ? reason : new Error(String(reason));\n try {\n this.config.onError(error, item);\n } catch {\n // Un onError roto no debe afectar al resto del flush.\n }\n }\n}\n","import type { StepPageLocation, UrlMatcher } from './types';\n\n/**\n * Matching de URL en CLIENTE (portado del backend `url-matcher.ts`). Lo usa el\n * motor composite para el targeting de página POR-PASO: como cada paso puede\n * apuntar a una página distinta (tours multi-página estilo Pendo), el SDK evalúa\n * la coincidencia en el navegador en cada navegación, no solo el backend.\n *\n * Errores de regex → `false` (no lanza): el patrón se validó al crear, pero una\n * fila corrupta no debe romper el render de una guía ajena.\n */\nexport function matchesUrl(matcher: UrlMatcher, pageUrl: string): boolean {\n switch (matcher.type) {\n case 'exact':\n return matcher.pattern === pageUrl;\n case 'prefix':\n return pageUrl.startsWith(matcher.pattern);\n case 'regex':\n try {\n return new RegExp(matcher.pattern).test(pageUrl);\n } catch {\n return false;\n }\n }\n}\n\n/** ¿El paso composite debe mostrarse en esta URL? Sitewide siempre; page → patrón. */\nexport function stepMatchesPage(\n loc: StepPageLocation | null | undefined,\n pageUrl: string,\n): boolean {\n if (!loc || loc.scope === 'sitewide' || !loc.pattern) return true;\n return matchesUrl({ type: loc.matchType ?? 'prefix', pattern: loc.pattern }, pageUrl);\n}\n","import { WALKTHROUGH_ABANDONMENT_TIMEOUT_MS, WALKTHROUGH_STATE_KEY_PREFIX } from './constants';\nimport type { WalkthroughState } from './types';\n\n/**\n * Estado persistente del walkthrough activo. Solo permite UNO por\n * workspace (namespace de apiKey). Vive en `localStorage` para sobrevivir\n * recargas de página: el step actual + el guideId alcanzan para resumir\n * desde donde quedó el usuario.\n *\n * Si pasan más de `WALKTHROUGH_ABANDONMENT_TIMEOUT_MS` sin progreso, se\n * considera abandonado: la próxima llamada a `current()` lo limpia\n * silenciosamente. NO se reporta `dismissed` al backend en ese caso —\n * abandonarse no es un acto del usuario.\n */\nexport class WalkthroughStateManager {\n private readonly storageKey: string;\n private state: WalkthroughState | null = null;\n\n constructor(namespace: string) {\n this.storageKey = `${WALKTHROUGH_STATE_KEY_PREFIX}${namespace}`;\n this.state = this.load();\n if (this.state && this.isAbandoned(this.state)) {\n this.clear();\n }\n }\n\n /**\n * Estado del walkthrough activo. Devuelve `null` si no hay ninguno o si\n * el último progreso fue hace más del timeout (en ese caso también\n * limpia el storage como side-effect).\n */\n current(): WalkthroughState | null {\n if (!this.state) return null;\n if (this.isAbandoned(this.state)) {\n this.clear();\n return null;\n }\n return this.state;\n }\n\n /** Atajo legible para el controller. */\n hasActive(): boolean {\n return this.current() !== null;\n }\n\n /**\n * Inicia un nuevo walkthrough en step 0. Sobreescribe cualquier estado\n * previo — los callers (controller) son responsables de verificar\n * `hasActive()` antes si necesitan exclusividad.\n */\n start(guideId: string, totalSteps: number): WalkthroughState {\n const now = Date.now();\n this.state = {\n guideId,\n totalSteps,\n currentStepIndex: 0,\n startedAt: now,\n lastProgressAt: now,\n };\n this.persist();\n return this.state;\n }\n\n /**\n * Avanza al siguiente step. Si el step resultante excede `totalSteps`,\n * devuelve `null` y NO toca el estado — el controller debe interpretar\n * eso como \"ya estamos en el último, no hay próximo\" y disparar\n * `complete` vía el handler del botón \"Finalizar\".\n */\n advance(): WalkthroughState | null {\n if (!this.state) return null;\n\n const next = this.state.currentStepIndex + 1;\n if (next >= this.state.totalSteps) return null;\n\n this.state = {\n ...this.state,\n currentStepIndex: next,\n lastProgressAt: Date.now(),\n };\n this.persist();\n return this.state;\n }\n\n /**\n * Retrocede al step anterior. En step 0 no hace nada y devuelve el\n * estado tal cual (el botón \"Atrás\" no debería estar visible en el\n * primer step, pero por defensa el manager también lo guard-ea).\n */\n back(): WalkthroughState | null {\n if (!this.state) return null;\n if (this.state.currentStepIndex === 0) return this.state;\n\n this.state = {\n ...this.state,\n currentStepIndex: this.state.currentStepIndex - 1,\n lastProgressAt: Date.now(),\n };\n this.persist();\n return this.state;\n }\n\n /** Limpia el estado activo (skip, complete, abandono, guía borrada). */\n clear(): void {\n this.state = null;\n if (typeof localStorage === 'undefined') return;\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n // Storage bloqueado — no rompemos la app.\n }\n }\n\n private isAbandoned(state: WalkthroughState): boolean {\n return Date.now() - state.lastProgressAt > WALKTHROUGH_ABANDONMENT_TIMEOUT_MS;\n }\n\n private load(): WalkthroughState | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(this.storageKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== 'object') return null;\n const candidate = parsed as Partial<WalkthroughState>;\n if (\n typeof candidate.guideId !== 'string' ||\n typeof candidate.totalSteps !== 'number' ||\n typeof candidate.currentStepIndex !== 'number' ||\n typeof candidate.startedAt !== 'number' ||\n typeof candidate.lastProgressAt !== 'number'\n ) {\n return null;\n }\n return candidate as WalkthroughState;\n } catch {\n return null;\n }\n }\n\n private persist(): void {\n if (typeof localStorage === 'undefined' || !this.state) return;\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(this.state));\n } catch {\n // Quota exceeded — silently fail. El walkthrough en memoria sigue.\n }\n }\n}\n","import type { VeoClient } from '../../types';\nimport {\n DEFAULT_TRACKER_BATCH_SIZE,\n DEFAULT_TRACKER_FLUSH_INTERVAL_MS,\n DEFAULT_TRACKER_MAX_RETRIES,\n} from './constants';\nimport { GuideFrequencyCache, namespaceFromApiKey } from './guide-frequency-cache';\nimport { GuideResolverClient } from './guide-resolver-client';\nimport { GuideTrackerClient } from './guide-tracker-client';\nimport { GuideTrackerQueue } from './guide-tracker-queue';\nimport { BadgeRenderer } from './renderers/badge-renderer';\nimport { BannerRenderer } from './renderers/banner-renderer';\nimport type { BaseRenderer } from './renderers/base-renderer';\nimport { CompositeRenderer } from './renderers/composite-renderer';\nimport { CustomRenderer } from './renderers/custom-renderer';\nimport { FormRenderer } from './renderers/form-renderer';\nimport { InlineCustomRenderer } from './renderers/inline-custom-renderer';\nimport { InlineFormRenderer } from './renderers/inline-form-renderer';\nimport { InlineRenderer } from './renderers/inline-renderer';\nimport { ModalRenderer } from './renderers/modal-renderer';\nimport { TooltipRenderer } from './renderers/tooltip-renderer';\nimport { WalkthroughRenderer } from './renderers/walkthrough-renderer';\nimport type {\n CompositeStep,\n FrequencyStatus,\n GuideInteractionAction,\n GuideInteractionEvent,\n GuideType,\n ResolvedGuide,\n WalkthroughCallbacks,\n} from './types';\nimport { stepMatchesPage } from './url-match';\nimport { WalkthroughStateManager } from './walkthrough-state';\n\nexport interface GuidesControllerConfig {\n apiUrl: string;\n apiKey: string;\n debug?: boolean;\n /** Override del resolver (tests). */\n resolver?: GuideResolverClient;\n /** Override del tracker queue (tests). */\n trackerQueue?: GuideTrackerQueue;\n /** Override del cache (tests). */\n frequencyCache?: GuideFrequencyCache;\n /** Override del walkthrough state manager (tests). */\n walkthroughState?: WalkthroughStateManager;\n}\n\n/**\n * Ventana durante la cual un `resolve` de la MISMA `(endUserId, url)` se sirve\n * de memoria sin pegarle al backend. Corta el doble disparo identify+pageview\n * en la carga y los pageviews repetidos de una SPA (mismo URL re-montado). Las\n * guías no son tiempo-real: 30 s de staleness es imperceptible y baja el\n * volumen de `/v1/guides/resolve` drásticamente con muchos usuarios.\n */\nconst RESOLVE_CACHE_TTL_MS = 30_000;\n\n/** Mapeo `action → cache status`. Solo acciones terminales mutan el cache. */\nconst STATUS_BY_ACTION: Record<GuideInteractionAction, FrequencyStatus | null> = {\n shown: 'shown',\n dismissed: 'dismissed',\n cta_clicked: null,\n step_advanced: null,\n step_back: null,\n completed: 'completed',\n};\n\n/**\n * Orquesta el ciclo de vida de las guías:\n *\n * 1. `pageview`/`identify` → `checkGuides(url, sessionId)`.\n * 2. Si hay un walkthrough activo (estado persistido en localStorage),\n * tiene prioridad: se intenta resumir en la página actual antes de\n * consultar nuevas guías. Si el selector del step actual aparece,\n * se pinta; si no, se cancela el walkthrough limpiamente.\n * 3. Si no hay walkthrough activo, se consulta `/v1/guides/resolve` y\n * se procesa cada guía:\n * - `walkthrough` con varios steps → arranca un walkthrough\n * (uno a la vez; el resto se ignora si ya hay uno).\n * - single-step → modal/banner/tooltip como antes.\n * 4. Cada interaction actualiza el cache local Y se encola para\n * `POST /v1/guides/:id/interactions`.\n *\n * Dedupe: `dispatched` guarda `${guideId}:${action}` ya encolados en la\n * sesión actual del SDK. Las acciones por-step de walkthroughs no\n * usan dedupe — cada `step_advanced` puede repetirse y representa una\n * navegación distinta.\n */\nexport class GuidesController {\n private readonly resolver: GuideResolverClient;\n private readonly trackerQueue: GuideTrackerQueue;\n private readonly frequencyCache: GuideFrequencyCache;\n private readonly walkthroughState: WalkthroughStateManager;\n private readonly debug: boolean;\n /** Para `POST /v1/guides/:id/form-response` (respuestas de guías form). */\n private readonly apiUrl: string;\n private readonly apiKey: string;\n private readonly activeRenderers = new Set<BaseRenderer>();\n /**\n * Guías single-step actualmente en pantalla, por `guideId`. Evita repintar/\n * duplicar la misma guía en cada pageview de una SPA (p.ej. una guía inline\n * anclada a un elemento persistente). Se libera al cerrarse la guía.\n */\n private readonly activeByGuideId = new Map<string, BaseRenderer>();\n private readonly dispatched = new Set<string>();\n /**\n * Renderer del paso de walkthrough activo. Puede ser el `WalkthroughRenderer`\n * (tooltip anclado) o un Modal/Banner con navegación (walkthrough heterogéneo);\n * tipamos por `destroy()`, lo único que el controller necesita.\n */\n private activeWalkthroughRenderer: { destroy(): void } | null = null;\n private activeWalkthroughGuide: ResolvedGuide | null = null;\n /** Última resolución cacheada (mismo `(endUserId, url)` → sin red). */\n private resolveCache: { key: string; at: number; guides: ResolvedGuide[] } | null = null;\n /** Resolución idéntica en vuelo, para coalescer llamadas concurrentes. */\n private inflightResolve: { key: string; promise: Promise<ResolvedGuide[]> } | null = null;\n /**\n * Disparadores por interacción armados (`on_click`/`on_hover`): guideId →\n * desarme del listener. Se re-arman desde cero en cada `checkGuides` (el\n * resolve fresco manda) y se limpian en `destroy()`.\n */\n private readonly armedTriggers = new Map<string, () => void>();\n /**\n * Tour composite ESPERANDO navegación: el usuario avanzó a un paso cuya\n * `pageLocation` apunta a otra página. Se resume en `checkGuides` cuando llega\n * a esa página (tours multi-página estilo Pendo).\n */\n private pendingComposite: { guide: ResolvedGuide; stepIndex: number } | null = null;\n\n constructor(\n private readonly client: VeoClient,\n config: GuidesControllerConfig,\n ) {\n this.debug = config.debug === true;\n this.apiUrl = config.apiUrl;\n this.apiKey = config.apiKey;\n this.resolver =\n config.resolver ?? new GuideResolverClient(config.apiUrl, config.apiKey, this.debug);\n\n if (config.trackerQueue) {\n this.trackerQueue = config.trackerQueue;\n } else {\n const httpClient = new GuideTrackerClient(config.apiUrl, config.apiKey);\n this.trackerQueue = new GuideTrackerQueue({\n client: httpClient,\n flushIntervalMs: DEFAULT_TRACKER_FLUSH_INTERVAL_MS,\n batchSize: DEFAULT_TRACKER_BATCH_SIZE,\n maxRetries: DEFAULT_TRACKER_MAX_RETRIES,\n onError: (err, item) => {\n if (this.debug) {\n console.warn(\n `[veo] dropped guide interaction after retries: guideId=${item.guideId} action=${item.payload.action}`,\n err,\n );\n }\n },\n });\n }\n\n const namespace = namespaceFromApiKey(config.apiKey);\n this.frequencyCache = config.frequencyCache ?? new GuideFrequencyCache(namespace);\n this.walkthroughState = config.walkthroughState ?? new WalkthroughStateManager(namespace);\n }\n\n /** Cuántas interactions hay pendientes de envío. Útil para debug en demo. */\n get pendingInteractions(): number {\n return this.trackerQueue.size;\n }\n\n /** Limpia el cache local (botón \"reset\" del demo, tests). */\n clearFrequencyCache(): void {\n this.frequencyCache.clear();\n }\n\n /** Limpia el walkthrough activo (debug del demo). */\n clearWalkthroughState(): void {\n this.tearDownWalkthrough();\n }\n\n /** Punto de entrada principal. Llamado en cada pageview/identify. */\n async checkGuides(pageUrl: string, sessionId: string): Promise<void> {\n const endUserId = this.client.getEndUserId();\n if (!endUserId) {\n if (this.debug) console.log('[veo] guides: skipped, no endUserId yet');\n return;\n }\n\n if (await this.tryResumeWalkthrough(endUserId, sessionId, pageUrl)) {\n return;\n }\n\n // Tour composite multi-página: si hay un paso pendiente que aplica a ESTA\n // página, resúmelo. No corta el resto del flujo (otras guías pueden mostrarse).\n this.tryResumeComposite(sessionId, pageUrl);\n\n let guides: ResolvedGuide[];\n try {\n guides = await this.resolveGuides(endUserId, pageUrl);\n } catch (err) {\n if (this.debug) console.error('[veo] guides resolver threw:', err);\n return;\n }\n if (this.debug) console.log(`[veo] guides: ${guides.length} eligible at ${pageUrl}`);\n\n // Los disparadores por interacción se re-arman desde el resolve fresco:\n // desarmar todo primero es idempotente y maneja las SPAs (la guía que ya\n // no aplica a esta URL no queda armada de una navegación anterior).\n this.disarmTriggers();\n\n for (const guide of guides) {\n const trigger = guide.activationRules.trigger;\n if ((trigger === 'on_click' || trigger === 'on_hover') && guide.activationRules.selector) {\n this.armInteractionTrigger(guide, endUserId, sessionId, pageUrl);\n continue;\n }\n await this.showGuide(guide, endUserId, sessionId, pageUrl);\n }\n }\n\n /**\n * Muestra una guía elegible (filtro de frecuencia + dedupe + dispatch por\n * tipo). Cuerpo original del loop de `checkGuides`, extraído para que los\n * disparadores por interacción pasen por LOS MISMOS chequeos al disparar.\n */\n private async showGuide(\n guide: ResolvedGuide,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<void> {\n if (this.frequencyCache.shouldFilter(guide.guideId, guide.displayFrequency)) {\n if (this.debug) console.log(`[veo] guides: filtered locally guideId=${guide.guideId}`);\n return;\n }\n\n // Ya está en pantalla → no repintar/duplicar (clave en SPAs: cada\n // navegación dispara un pageview, pero la guía sigue montada).\n if (this.activeByGuideId.has(guide.guideId)) {\n if (this.debug) console.log(`[veo] guides: already shown guideId=${guide.guideId}`);\n return;\n }\n\n if (guide.guideType === 'walkthrough' && guide.guideSteps.length > 1) {\n if (this.walkthroughState.hasActive()) {\n if (this.debug)\n console.log(`[veo] guides: walkthrough ${guide.guideId} skipped (another active)`);\n return;\n }\n await this.startWalkthrough(guide, endUserId, sessionId, pageUrl);\n // Las guías single-step pueden seguir mostrándose en paralelo. Solo se\n // bloquean OTROS walkthroughs vía hasActive().\n return;\n }\n\n // Modelo unificado: targeting de página POR-PASO + navegación multi-paso.\n if (guide.guideType === 'composite') {\n this.startComposite(guide, sessionId, pageUrl);\n return;\n }\n\n this.runSingleStepRender(guide, sessionId, pageUrl);\n }\n\n /**\n * Arma un disparador por interacción: la guía NO se muestra al cargar, sino\n * cuando el usuario hace click / pasa el mouse sobre `activationRules.selector`.\n * Listener DELEGADO en `document` (fase captura, sin preventDefault — el click\n * original de la app sigue funcionando). Al disparar se desarma y la guía pasa\n * por `showGuide` (mismos chequeos de frecuencia/dedupe). Tras cerrarse, el\n * próximo pageview/identify la re-arma — hover/click vuelve a mostrarla\n * mientras la frecuencia lo permita.\n */\n private armInteractionTrigger(\n guide: ResolvedGuide,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): void {\n // Armar solo lo que tiene sentido mostrar: si la frecuencia ya la filtra o\n // ya está en pantalla, no escuchamos de más.\n if (this.frequencyCache.shouldFilter(guide.guideId, guide.displayFrequency)) return;\n if (this.activeByGuideId.has(guide.guideId)) return;\n if (this.armedTriggers.has(guide.guideId)) return;\n\n const selector = guide.activationRules.selector as string;\n const eventName = guide.activationRules.trigger === 'on_hover' ? 'mouseover' : 'click';\n\n const onFire = (e: Event): void => {\n const target = e.target;\n if (!(target instanceof Element)) return;\n try {\n if (!target.closest(selector)) return;\n } catch {\n return; // selector inválido en la DB: no romper la app\n }\n disarm();\n void this.showGuide(guide, endUserId, sessionId, pageUrl);\n };\n const disarm = (): void => {\n document.removeEventListener(eventName, onFire, true);\n this.armedTriggers.delete(guide.guideId);\n };\n\n document.addEventListener(eventName, onFire, true);\n this.armedTriggers.set(guide.guideId, disarm);\n if (this.debug)\n console.log(`[veo] guides: armed ${eventName} trigger for ${guide.guideId} on ${selector}`);\n }\n\n /** Desarma todos los disparadores por interacción pendientes. */\n private disarmTriggers(): void {\n for (const disarm of this.armedTriggers.values()) disarm();\n this.armedTriggers.clear();\n }\n\n /**\n * `resolve` con cache de corta duración + coalescing:\n * - Mismo `(endUserId, url)` resuelto hace < {@link RESOLVE_CACHE_TTL_MS} →\n * se reusa sin red. Colapsa el doble disparo identify+pageview y los\n * pageviews repetidos de una SPA hacia la misma URL.\n * - Si ya hay un resolve idéntico en vuelo, se espera ESE (no se abre otro).\n * El re-render sigue siendo idempotente (dedupe por `activeByGuideId` +\n * `frequencyCache`), así que reusar el resultado no duplica guías.\n */\n private async resolveGuides(endUserId: string, pageUrl: string): Promise<ResolvedGuide[]> {\n const key = `${endUserId}\\n${pageUrl}`;\n const now = Date.now();\n\n if (this.resolveCache?.key === key && now - this.resolveCache.at < RESOLVE_CACHE_TTL_MS) {\n if (this.debug) console.log('[veo] guides: resolve cache hit');\n return this.resolveCache.guides;\n }\n\n if (this.inflightResolve?.key === key) {\n return this.inflightResolve.promise;\n }\n\n const promise = this.resolver.resolve(endUserId, pageUrl);\n this.inflightResolve = { key, promise };\n try {\n const guides = await promise;\n this.resolveCache = { key, at: Date.now(), guides };\n return guides;\n } finally {\n if (this.inflightResolve?.key === key) this.inflightResolve = null;\n }\n }\n\n /** Cierra todas las guías activas, limpia cache de dispatch y para timers. */\n destroy(): void {\n for (const renderer of this.activeRenderers) {\n try {\n renderer.destroy();\n } catch (err) {\n if (this.debug) console.error('[veo] renderer destroy failed:', err);\n }\n }\n this.activeRenderers.clear();\n this.activeByGuideId.clear();\n if (this.activeWalkthroughRenderer) {\n try {\n this.activeWalkthroughRenderer.destroy();\n } catch {\n // swallow — el cleanup no debe propagar\n }\n this.activeWalkthroughRenderer = null;\n this.activeWalkthroughGuide = null;\n }\n this.disarmTriggers();\n this.dispatched.clear();\n this.resolveCache = null;\n this.inflightResolve = null;\n this.trackerQueue.destroy();\n }\n\n private runSingleStepRender(guide: ResolvedGuide, sessionId: string, pageUrl: string): void {\n const renderer = this.createSingleStepRenderer(guide.guideType);\n if (!renderer) return;\n\n // Reservar el slot YA (antes del delay) para que pageviews rápidos no\n // disparen dos renders de la misma guía.\n this.activeByGuideId.set(guide.guideId, renderer);\n\n const delayMs = guide.activationRules.delayMs ?? 0;\n window.setTimeout(\n () => this.mountSingleStepRenderer(guide, renderer, sessionId, pageUrl),\n delayMs,\n );\n }\n\n /**\n * Camino del modelo unificado (`composite`). Elige el PRIMER paso cuya\n * `pageLocation` matchea la URL actual (targeting por-paso) y lo pinta con el\n * `CompositeRenderer`. Si ningún paso aplica a esta página, no muestra nada.\n */\n private startComposite(guide: ResolvedGuide, sessionId: string, pageUrl: string): void {\n // Ya hay un tour de esta guía a mitad de camino (esperando navegación) → no\n // reiniciar desde el paso 0; el resume lo maneja `tryResumeComposite`.\n if (this.pendingComposite?.guide.guideId === guide.guideId) return;\n const steps = guide.guideSteps as unknown as CompositeStep[];\n const start = steps.findIndex((s) => stepMatchesPage(s.pageLocation, pageUrl));\n if (start === -1) return; // ningún paso aplica a esta URL\n this.renderCompositeStep(guide, start, sessionId, pageUrl);\n }\n\n /**\n * Resume un tour composite que quedó esperando navegación: si el paso\n * pendiente aplica a la página actual, lo pinta. Devuelve `true` si resumió.\n */\n private tryResumeComposite(sessionId: string, pageUrl: string): boolean {\n const pending = this.pendingComposite;\n if (!pending) return false;\n const steps = pending.guide.guideSteps as unknown as CompositeStep[];\n const step = steps[pending.stepIndex];\n if (!step) {\n this.pendingComposite = null;\n return false;\n }\n if (!stepMatchesPage(step.pageLocation, pageUrl)) return false; // aún no llegó\n this.pendingComposite = null;\n this.renderCompositeStep(pending.guide, pending.stepIndex, sessionId, pageUrl);\n return true;\n }\n\n /**\n * Pinta UN paso composite. En guías multi-paso pasa `nav` al renderer para\n * que los botones next/prev avancen (misma página); en single-step los\n * botones cierran. Cada avance destruye el paso anterior y monta el siguiente.\n */\n private renderCompositeStep(\n guide: ResolvedGuide,\n idx: number,\n sessionId: string,\n pageUrl: string,\n ): void {\n const steps = guide.guideSteps as unknown as CompositeStep[];\n const renderer = new CompositeRenderer();\n this.activeRenderers.add(renderer);\n this.activeByGuideId.set(guide.guideId, renderer);\n\n const cleanup = (): void => {\n renderer.destroy();\n this.activeRenderers.delete(renderer);\n if (this.activeByGuideId.get(guide.guideId) === renderer) {\n this.activeByGuideId.delete(guide.guideId);\n }\n };\n\n // Avanza a `target`: si ese paso aplica a la página ACTUAL lo pinta ya\n // (tour misma-página); si apunta a OTRA página, guarda el pendiente y espera\n // a que el usuario navegue (tour multi-página, se resume en `checkGuides`).\n const goToStep = (target: number): void => {\n cleanup();\n if (target < 0 || target >= steps.length) return; // fuera de rango → fin\n const step = steps[target];\n if (step && stepMatchesPage(step.pageLocation, pageUrl)) {\n this.renderCompositeStep(guide, target, sessionId, pageUrl);\n } else {\n this.pendingComposite = { guide, stepIndex: target };\n }\n };\n\n const nav =\n steps.length > 1\n ? {\n stepIndex: idx,\n totalSteps: steps.length,\n callbacks: {\n onNext: (): void => goToStep(idx + 1),\n onBack: (): void => goToStep(idx - 1),\n onGoto: (target: number): void => goToStep(target),\n onSkip: cleanup,\n onComplete: cleanup,\n },\n }\n : undefined;\n\n try {\n void renderer.render({\n guide,\n onInteraction: (e) => this.handleInteraction(guide, sessionId, pageUrl, e),\n onClose: cleanup,\n onTrack: (name, props) => this.client.track(name, props),\n onFormSubmit: (answers) => this.submitFormResponse(guide.guideId, answers),\n onOpenGuide: (targetGuideId) => {\n void this.openGuideById(targetGuideId, sessionId, pageUrl);\n },\n ...(nav ? { nav } : {}),\n });\n } catch (err) {\n if (this.debug) console.error('[veo] composite renderer threw:', err);\n cleanup();\n }\n }\n\n private mountSingleStepRenderer(\n guide: ResolvedGuide,\n renderer: BaseRenderer,\n sessionId: string,\n pageUrl: string,\n ): void {\n this.activeRenderers.add(renderer);\n this.activeByGuideId.set(guide.guideId, renderer);\n\n const onClose = (): void => {\n renderer.destroy();\n this.activeRenderers.delete(renderer);\n if (this.activeByGuideId.get(guide.guideId) === renderer) {\n this.activeByGuideId.delete(guide.guideId);\n }\n };\n\n const onInteraction = (event: GuideInteractionEvent): void => {\n this.handleInteraction(guide, sessionId, pageUrl, event);\n };\n\n const onTrack = (eventName: string, properties?: Record<string, unknown>): void => {\n this.client.track(eventName, properties);\n };\n\n const onFormSubmit = (answers: Record<string, unknown>): Promise<boolean> =>\n this.submitFormResponse(guide.guideId, answers);\n\n // Encadenado: un botón `action:'guide'` abre otra guía por id.\n const onOpenGuide = (targetGuideId: string): void => {\n void this.openGuideById(targetGuideId, sessionId, pageUrl);\n };\n\n try {\n void renderer.render({ guide, onInteraction, onClose, onTrack, onFormSubmit, onOpenGuide });\n } catch (err) {\n if (this.debug) console.error('[veo] renderer.render threw:', err);\n this.activeRenderers.delete(renderer);\n if (this.activeByGuideId.get(guide.guideId) === renderer) {\n this.activeByGuideId.delete(guide.guideId);\n }\n }\n }\n\n /**\n * Abre una guía POR ID, disparada desde el botón de otra guía (encadenado).\n * Ignora las URL rules y el trigger (el autor lo pidió explícitamente desde\n * un botón); respeta el dedupe de guías activas y el flujo normal de\n * tracking. 404/red → no-op (la guía destino pudo borrarse).\n */\n private async openGuideById(guideId: string, sessionId: string, pageUrl: string): Promise<void> {\n if (this.activeByGuideId.has(guideId)) return;\n const guide = await this.resolver.fetchById(guideId);\n if (!guide) {\n if (this.debug) console.warn(`[veo] guides: chained guide ${guideId} not found`);\n return;\n }\n const endUserId = this.client.getEndUserId() ?? this.client.getAnonymousId();\n if (guide.guideType === 'walkthrough' && guide.guideSteps.length > 1) {\n if (!this.walkthroughState.hasActive()) {\n await this.startWalkthrough(guide, endUserId, sessionId, pageUrl);\n }\n return;\n }\n this.runSingleStepRender(guide, sessionId, pageUrl);\n }\n\n /**\n * Si hay un walkthrough persistido, intenta pintar el step actual en\n * la página actual. Retorna `true` si lo intentó (sea éxito o cancel),\n * `false` si no había walkthrough activo.\n *\n * Cancela limpiamente (sin enviar `dismissed` falso) cuando:\n * - La guía fue eliminada en el backend (404 → `fetchById` devuelve null).\n * - La guía cambió de tipo y ya no es walkthrough.\n * - El selector del step actual no aparece dentro del timeout.\n */\n private async tryResumeWalkthrough(\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<boolean> {\n const state = this.walkthroughState.current();\n if (!state) return false;\n\n const guide = await this.resolver.fetchById(state.guideId);\n if (!guide || guide.guideType !== 'walkthrough') {\n if (this.debug)\n console.log(`[veo] guides: walkthrough ${state.guideId} no longer available, cleaning up`);\n this.tearDownWalkthrough();\n return true;\n }\n\n // El cache local podría tener una versión más vieja del total; usamos\n // siempre el del backend.\n const stepIndex = Math.min(state.currentStepIndex, guide.guideSteps.length - 1);\n await this.renderWalkthroughStep(guide, stepIndex, endUserId, sessionId, pageUrl);\n return true;\n }\n\n private async startWalkthrough(\n guide: ResolvedGuide,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<void> {\n this.walkthroughState.start(guide.guideId, guide.guideSteps.length);\n const rendered = await this.renderWalkthroughStep(guide, 0, endUserId, sessionId, pageUrl);\n if (!rendered) return; // teardown ya corrió, no reportamos shown.\n // Reportamos `shown` SOLO al arrancar (step 0). Steps siguientes\n // se cubren con `step_advanced`/`step_back`. Marcamos cache local\n // también para que `displayFrequency='once'` filtre en la próxima\n // pageview aunque la interaction aún esté en la queue.\n this.enqueueInteractionOnce(guide.guideId, endUserId, sessionId, pageUrl, 'shown', 0);\n this.frequencyCache.record(guide.guideId, 'shown');\n }\n\n /**\n * Pinta el step indicado. Reusa la guía (no fetcha): el caller debe\n * traerla. Retorna `true` si el render fue exitoso. En caso contrario\n * ya disparó el teardown — el caller no debe seguir reportando.\n */\n private async renderWalkthroughStep(\n guide: ResolvedGuide,\n stepIndex: number,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n ): Promise<boolean> {\n if (this.activeWalkthroughRenderer) {\n this.activeWalkthroughRenderer.destroy();\n this.activeWalkthroughRenderer = null;\n }\n\n this.activeWalkthroughGuide = guide;\n\n const callbacks: WalkthroughCallbacks = {\n onNext: () => this.handleWalkthroughNext(endUserId, sessionId, pageUrl),\n onBack: () => this.handleWalkthroughBack(endUserId, sessionId, pageUrl),\n onSkip: () => this.handleWalkthroughSkip(endUserId, sessionId, pageUrl),\n onComplete: () => this.handleWalkthroughComplete(endUserId, sessionId, pageUrl),\n };\n\n // Walkthrough HETEROGÉNEO: un paso puede pedir renderizarse como modal o\n // banner (via `step.style.render`). Esos renderers siempre montan (no\n // dependen de un ancla), así que reportamos éxito directo. El resto\n // (tooltip/default) usa el WalkthroughRenderer anclado.\n const step = guide.guideSteps[stepIndex];\n const render = readStepRender(step);\n if (render === 'modal' || render === 'banner') {\n const renderer = render === 'modal' ? new ModalRenderer() : new BannerRenderer();\n try {\n renderer.render({\n guide,\n onInteraction: () => {},\n onClose: () => {},\n nav: { stepIndex, totalSteps: guide.guideSteps.length, callbacks },\n });\n } catch (err) {\n if (this.debug) console.error('[veo] sequence renderer threw:', err);\n this.tearDownWalkthrough();\n return false;\n }\n this.activeWalkthroughRenderer = renderer;\n return true;\n }\n\n const renderer = new WalkthroughRenderer();\n let success = false;\n try {\n success = await renderer.render({ guide, currentStepIndex: stepIndex, callbacks });\n } catch (err) {\n if (this.debug) console.error('[veo] walkthrough renderer threw:', err);\n }\n\n if (!success) {\n if (this.debug)\n console.warn(\n `[veo] walkthrough ${guide.guideId} step ${stepIndex} could not render, cancelling`,\n );\n this.tearDownWalkthrough();\n return false;\n }\n\n this.activeWalkthroughRenderer = renderer;\n return true;\n }\n\n private handleWalkthroughNext(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n if (!guide) return;\n\n const newState = this.walkthroughState.advance();\n if (!newState) {\n // Ya estábamos en el último step. No debería pasar (el botón\n // dispara onComplete en ese caso), pero por defensa lo manejamos.\n this.handleWalkthroughComplete(endUserId, sessionId, pageUrl);\n return;\n }\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'step_advanced',\n newState.currentStepIndex,\n );\n void this.renderWalkthroughStep(\n guide,\n newState.currentStepIndex,\n endUserId,\n sessionId,\n pageUrl,\n );\n }\n\n private handleWalkthroughBack(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n if (!guide) return;\n\n const state = this.walkthroughState.current();\n if (!state || state.currentStepIndex === 0) return;\n\n const newState = this.walkthroughState.back();\n if (!newState) return;\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'step_back',\n newState.currentStepIndex,\n );\n void this.renderWalkthroughStep(\n guide,\n newState.currentStepIndex,\n endUserId,\n sessionId,\n pageUrl,\n );\n }\n\n private handleWalkthroughSkip(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n const state = this.walkthroughState.current();\n if (!guide || !state) return;\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'dismissed',\n state.currentStepIndex,\n );\n this.frequencyCache.record(guide.guideId, 'dismissed');\n this.tearDownWalkthrough();\n }\n\n private handleWalkthroughComplete(endUserId: string, sessionId: string, pageUrl: string): void {\n const guide = this.activeWalkthroughGuide;\n const state = this.walkthroughState.current();\n if (!guide || !state) return;\n\n this.enqueueInteraction(\n guide.guideId,\n endUserId,\n sessionId,\n pageUrl,\n 'completed',\n state.currentStepIndex,\n );\n this.frequencyCache.record(guide.guideId, 'completed');\n this.tearDownWalkthrough();\n }\n\n private tearDownWalkthrough(): void {\n if (this.activeWalkthroughRenderer) {\n try {\n this.activeWalkthroughRenderer.destroy();\n } catch {\n // swallow\n }\n }\n this.activeWalkthroughRenderer = null;\n this.activeWalkthroughGuide = null;\n this.walkthroughState.clear();\n }\n\n /**\n * Tras cada interaction single-step:\n * 1. dedupe (no enviar 2× la misma `(guideId, action)` por sesión)\n * 2. actualizar el cache local si corresponde\n * 3. encolar el POST\n *\n * El endUserId se lee del client EN ESTE MOMENTO (no en el render),\n * por si el usuario se identificó después de que la guía apareció.\n */\n private handleInteraction(\n guide: ResolvedGuide,\n sessionId: string,\n pageUrl: string,\n event: GuideInteractionEvent,\n ): void {\n // Con varios botones por paso, cada botón cuenta aparte: el buttonId entra\n // a la key (si no, el segundo botón clickeado se perdería por dedup).\n const buttonKey = event.metadata?.buttonId ? `:${event.metadata.buttonId}` : '';\n const dedupKey = `${guide.guideId}:${event.action}${buttonKey}`;\n if (this.dispatched.has(dedupKey)) {\n if (this.debug) console.log(`[veo] guides: dedup hit ${dedupKey}`);\n return;\n }\n this.dispatched.add(dedupKey);\n\n const cacheStatus = STATUS_BY_ACTION[event.action];\n if (cacheStatus) this.frequencyCache.record(guide.guideId, cacheStatus);\n\n const endUserId = this.client.getEndUserId();\n if (!endUserId) {\n if (this.debug)\n console.warn('[veo] guides: interaction without endUserId — skipping enqueue');\n return;\n }\n\n this.trackerQueue.enqueue({\n guideId: guide.guideId,\n payload: {\n endUserId,\n sessionId,\n action: event.action,\n stepIndex: event.stepIndex,\n pageUrl,\n pagePath: extractPath(pageUrl),\n ...(event.metadata ? { metadata: event.metadata } : {}),\n },\n });\n }\n\n /**\n * Encola una interacción de walkthrough SIN pasar por el dedup set.\n * Acciones como `step_advanced` se repiten naturalmente (cada next es\n * una navegación distinta) y deduplicarlas perdería datos.\n */\n private enqueueInteraction(\n guideId: string,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n action: GuideInteractionAction,\n stepIndex: number,\n ): void {\n this.trackerQueue.enqueue({\n guideId,\n payload: {\n endUserId,\n sessionId,\n action,\n stepIndex,\n pageUrl,\n pagePath: extractPath(pageUrl),\n },\n });\n }\n\n /**\n * Encola con dedup por sesión del SDK. Para `shown` del primer step:\n * no queremos re-emitirlo si el usuario navega entre dos páginas que\n * matchean el mismo step.\n */\n private enqueueInteractionOnce(\n guideId: string,\n endUserId: string,\n sessionId: string,\n pageUrl: string,\n action: GuideInteractionAction,\n stepIndex: number,\n ): void {\n const dedupKey = `${guideId}:${action}:${stepIndex}`;\n if (this.dispatched.has(dedupKey)) return;\n this.dispatched.add(dedupKey);\n this.enqueueInteraction(guideId, endUserId, sessionId, pageUrl, action, stepIndex);\n }\n\n private createSingleStepRenderer(type: GuideType): BaseRenderer | null {\n switch (type) {\n case 'modal':\n return new ModalRenderer();\n case 'banner':\n return new BannerRenderer();\n case 'tooltip':\n return new TooltipRenderer();\n case 'custom':\n return new CustomRenderer();\n case 'inline':\n return new InlineRenderer();\n case 'inline-custom':\n return new InlineCustomRenderer();\n case 'form':\n return new FormRenderer();\n case 'inline-form':\n return new InlineFormRenderer();\n case 'badge':\n return new BadgeRenderer();\n case 'composite':\n return new CompositeRenderer();\n case 'walkthrough':\n return null;\n default:\n return null;\n }\n }\n\n /**\n * Envía las respuestas de una guía `form` al backend, que las mergea como\n * propiedades del usuario. Usa el endUserId actual (o el anónimo si aún no\n * hubo identify — el backend pre-crea la fila igual que identify).\n */\n private async submitFormResponse(\n guideId: string,\n answers: Record<string, unknown>,\n ): Promise<boolean> {\n const endUserId = this.client.getEndUserId() ?? this.client.getAnonymousId();\n try {\n const res = await fetch(`${this.apiUrl}/v1/guides/${guideId}/form-response`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': this.apiKey },\n body: JSON.stringify({ endUserId, answers }),\n });\n if (!res.ok && this.debug) {\n console.warn('[veo] form-response respondió', res.status);\n }\n return res.ok;\n } catch (err) {\n if (this.debug) console.warn('[veo] form-response falló:', err);\n return false;\n }\n }\n}\n\nfunction extractPath(url: string): string {\n try {\n return new URL(url).pathname;\n } catch {\n return '/';\n }\n}\n\n/**\n * Cómo se presenta un paso dentro de un walkthrough. `style.render` ∈\n * `modal`/`banner` usa esos renderers (con navegación); cualquier otro valor\n * (incluido ausente o `tooltip`) usa el WalkthroughRenderer anclado.\n */\nfunction readStepRender(step: ResolvedGuide['guideSteps'][number] | undefined): string {\n const r = (step?.style as Record<string, unknown> | null | undefined)?.render;\n return typeof r === 'string' ? r : 'walkthrough';\n}\n","import type { VeoPlugin } from '../../types';\nimport { hasWindow } from '../../utils/safe-env';\nimport { definePlugin } from '../plugin';\nimport { GuidesController } from './guides-controller';\n\nexport interface GuidesPluginConfig {\n apiUrl: string;\n apiKey: string;\n debug?: boolean;\n}\n\n/** Resultado del install — expone el controller para debugging desde el demo. */\nexport interface GuidesPluginHandle {\n controller: GuidesController;\n}\n\n/**\n * Plugin que renderiza guías in-app (modal/banner/tooltip) consultando\n * `GET /v1/guides/resolve` y registra las interacciones en\n * `POST /v1/guides/:id/interactions` vía queue dedicada con retry y\n * sendBeacon en pagehide.\n *\n * Opt-in: `init({ ..., guides: true })`. El plugin escucha\n * `pageview` e `identify` del client; el payload del evento ya trae\n * `sessionId` y `endUserId` para que no necesitemos consultar al\n * client en cada disparo.\n *\n * Frequency híbrida: el backend filtra autoritariamente; el cache\n * local (`GuideFrequencyCache`) solo previene el flash visual cuando\n * la interaction aún no se persistió.\n */\nexport function guidesPlugin(config: GuidesPluginConfig): VeoPlugin {\n return definePlugin({\n name: 'guides',\n install(client) {\n if (!hasWindow()) return;\n const controller = new GuidesController(client, config);\n\n // Exponer el controller en window para que el demo y tests E2E\n // puedan inspeccionar el cache y la queue.\n (window as unknown as { __veoGuides?: GuidesPluginHandle }).__veoGuides = { controller };\n\n client.on('identify', ({ sessionId }) => {\n void controller.checkGuides(window.location.href, sessionId);\n });\n\n client.on('pageview', ({ url, sessionId }) => {\n void controller.checkGuides(url, sessionId);\n });\n\n // Como el bundle de guías se carga PEREZOSAMENTE, el plugin puede\n // instalarse DESPUÉS del pageview/identify inicial — esos eventos ya\n // pasaron. Chequeamos la página actual ahora mismo para que la guía\n // aparezca apenas se entra (sin necesitar una 2ª acción). Si todavía no\n // hay endUserId, checkGuides no hace nada y el listener de `identify` la\n // mostrará; el dedupe por guideId evita un doble render.\n void controller.checkGuides(window.location.href, client.getSessionId());\n },\n });\n}\n\nexport type { PreviewGuideInput, PreviewHandle, PreviewResult } from './guide-preview';\nexport { closeGuidePreview, previewGuide } from './guide-preview';\nexport type { PreviewModeHandle, PreviewModeOptions } from './preview-mode';\nexport { runPreviewMode } from './preview-mode';\nexport type { GuideInteractionEvent, GuideStep, ResolvedGuide } from './types';\n"]}