veo-sdk 0.6.3 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -441,13 +441,14 @@ var init_activation_rules = __esm({
441
441
  });
442
442
 
443
443
  // src/plugins/guides/constants.ts
444
- var GUIDE_Z_INDEX, DEFAULT_ANCHOR_WAIT_MS, SAFE_URL_PROTOCOLS, GUIDE_HOST_ATTR, FREQUENCY_CACHE_KEY_PREFIX, DEFAULT_TRACKER_FLUSH_INTERVAL_MS, DEFAULT_TRACKER_BATCH_SIZE, DEFAULT_TRACKER_MAX_RETRIES, FREQUENCY_CACHE_MAX_ENTRIES, FREQUENCY_CACHE_TTL_MS, WALKTHROUGH_STATE_KEY_PREFIX, WALKTHROUGH_ABANDONMENT_TIMEOUT_MS, WALKTHROUGH_STEP_SELECTOR_TIMEOUT_MS;
444
+ var GUIDE_Z_INDEX, DEFAULT_ANCHOR_WAIT_MS, SAFE_URL_PROTOCOLS, GUIDE_HOST_ATTR, BADGE_MARKER_HOST_ATTR, FREQUENCY_CACHE_KEY_PREFIX, DEFAULT_TRACKER_FLUSH_INTERVAL_MS, DEFAULT_TRACKER_BATCH_SIZE, DEFAULT_TRACKER_MAX_RETRIES, FREQUENCY_CACHE_MAX_ENTRIES, FREQUENCY_CACHE_TTL_MS, WALKTHROUGH_STATE_KEY_PREFIX, WALKTHROUGH_ABANDONMENT_TIMEOUT_MS, WALKTHROUGH_STEP_SELECTOR_TIMEOUT_MS;
445
445
  var init_constants2 = __esm({
446
446
  "src/plugins/guides/constants.ts"() {
447
447
  GUIDE_Z_INDEX = 2147483640;
448
448
  DEFAULT_ANCHOR_WAIT_MS = 5e3;
449
449
  SAFE_URL_PROTOCOLS = ["http:", "https:"];
450
450
  GUIDE_HOST_ATTR = "data-veo-guide";
451
+ BADGE_MARKER_HOST_ATTR = "data-veo-badge";
451
452
  FREQUENCY_CACHE_KEY_PREFIX = "veo:freq:";
452
453
  DEFAULT_TRACKER_FLUSH_INTERVAL_MS = 3e3;
453
454
  DEFAULT_TRACKER_BATCH_SIZE = 5;
@@ -2057,6 +2058,25 @@ var init_base_renderer = __esm({
2057
2058
  this.shadow = shadow;
2058
2059
  return { host, shadow, root };
2059
2060
  }
2061
+ /**
2062
+ * Host SUELTO con los mismos estilos (shadow DOM), sin agregarlo al DOM ni
2063
+ * registrarlo como `this.host`. Para piezas que deben vivir dentro de la app
2064
+ * (el marcador de un badge, junto a su ancla) mientras la tarjeta se queda
2065
+ * en `body`: si la tarjeta viajara dentro del ancla, un ancestro con
2066
+ * `transform`/`overflow` la recortaría y su z-index quedaría atrapado.
2067
+ */
2068
+ createDetachedHost(attr = BADGE_MARKER_HOST_ATTR) {
2069
+ const host = document.createElement("div");
2070
+ host.setAttribute(attr, "");
2071
+ const shadow = host.attachShadow({ mode: "open" });
2072
+ const style = document.createElement("style");
2073
+ style.textContent = GUIDE_STYLES;
2074
+ shadow.appendChild(style);
2075
+ const root = document.createElement("div");
2076
+ shadow.appendChild(root);
2077
+ this.registerCleanup(() => host.remove());
2078
+ return { host, root };
2079
+ }
2060
2080
  /**
2061
2081
  * Aplica la tematización por datos del step (`step.style`) como variables
2062
2082
  * CSS sobre el host. Llamar tras `createHost()`. No-op si no hay host o
@@ -3593,6 +3613,18 @@ var init_snooze = __esm({
3593
3613
  };
3594
3614
  }
3595
3615
  });
3616
+
3617
+ // src/plugins/guides/z-index.ts
3618
+ function clampZIndex(value, fallback) {
3619
+ if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
3620
+ return Math.max(-MAX_Z_INDEX, Math.min(MAX_Z_INDEX, Math.round(value)));
3621
+ }
3622
+ var MAX_Z_INDEX;
3623
+ var init_z_index = __esm({
3624
+ "src/plugins/guides/z-index.ts"() {
3625
+ MAX_Z_INDEX = 2147483647;
3626
+ }
3627
+ });
3596
3628
  function num(v, fallback) {
3597
3629
  return typeof v === "number" && Number.isFinite(v) ? v : fallback;
3598
3630
  }
@@ -3742,7 +3774,7 @@ function canNest(anchor) {
3742
3774
  }
3743
3775
  function attachMarker(anchor, host, marker) {
3744
3776
  host.style.position = "absolute";
3745
- host.style.zIndex = String(num(marker.zIndex, DEFAULT_MARKER_Z));
3777
+ host.style.zIndex = String(clampZIndex(marker.zIndex, DEFAULT_MARKER_Z));
3746
3778
  host.style.margin = "0";
3747
3779
  const position = marker.position ?? "top-right";
3748
3780
  const offset6 = { x: num(marker.offsetX, 0), y: num(marker.offsetY, 0) };
@@ -3817,6 +3849,7 @@ function attachMarker(anchor, host, marker) {
3817
3849
  var INFO_GLYPH, QUESTION_GLYPH, STAR_GLYPH, CIRCLE, TARGET_GLYPH, BADGE_ICONS, DEFAULT_MARKER_SIZE, DEFAULT_MARKER_Z, SIDE_GAP, NO_CHILDREN;
3818
3850
  var init_badge_marker = __esm({
3819
3851
  "src/plugins/guides/renderers/badge-marker.ts"() {
3852
+ init_z_index();
3820
3853
  INFO_GLYPH = "M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021";
3821
3854
  QUESTION_GLYPH = "M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75";
3822
3855
  STAR_GLYPH = "M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z";
@@ -3943,7 +3976,7 @@ function liftTarget(anchor, zIndex) {
3943
3976
  const prevPosition = el2.style.position;
3944
3977
  const prevZ = el2.style.zIndex;
3945
3978
  if (getComputedStyle(el2).position === "static") el2.style.position = "relative";
3946
- el2.style.zIndex = String(zIndex);
3979
+ el2.style.zIndex = String(clampZIndex(zIndex, 0));
3947
3980
  return () => {
3948
3981
  el2.style.position = prevPosition;
3949
3982
  el2.style.zIndex = prevZ;
@@ -4034,6 +4067,7 @@ var init_composite_renderer = __esm({
4034
4067
  init_scroll_lock();
4035
4068
  init_snooze();
4036
4069
  init_wait_for_element();
4070
+ init_z_index();
4037
4071
  init_badge_marker();
4038
4072
  init_base_renderer();
4039
4073
  init_floating_arrow();
@@ -4081,7 +4115,9 @@ var init_composite_renderer = __esm({
4081
4115
  const { host, root } = this.createHost();
4082
4116
  const doc = root.ownerDocument ?? document;
4083
4117
  const design = step.design ?? {};
4084
- if (typeof design.zIndex === "number") host.style.zIndex = String(design.zIndex);
4118
+ if (typeof design.zIndex === "number") {
4119
+ host.style.zIndex = String(clampZIndex(design.zIndex, 0));
4120
+ }
4085
4121
  const card = doc.createElement("div");
4086
4122
  card.className = "veo-card";
4087
4123
  const themeMode = themeModeFor(context.guide.theme, design);
@@ -4190,7 +4226,7 @@ var init_composite_renderer = __esm({
4190
4226
  const bg = doc.createElement("div");
4191
4227
  bg.className = "veo-composite-overlay veo-composite-overlay--dim";
4192
4228
  if (typeof design.backdropColor === "string") bg.style.background = design.backdropColor;
4193
- const bz = typeof design.backdropZIndex === "number" ? design.backdropZIndex : 2e5;
4229
+ const bz = clampZIndex(design.backdropZIndex, 2e5);
4194
4230
  bg.style.zIndex = String(bz);
4195
4231
  root.appendChild(bg);
4196
4232
  this.registerCleanup(lockScroll(doc));
@@ -4212,7 +4248,7 @@ var init_composite_renderer = __esm({
4212
4248
  overlay.style.background = design.backdropColor;
4213
4249
  }
4214
4250
  if (typeof design.backdropZIndex === "number") {
4215
- overlay.style.zIndex = String(design.backdropZIndex);
4251
+ overlay.style.zIndex = String(clampZIndex(design.backdropZIndex, 0));
4216
4252
  }
4217
4253
  overlay.addEventListener("click", (e) => {
4218
4254
  if (e.target === overlay) {
@@ -4533,6 +4569,7 @@ var init_composite_renderer = __esm({
4533
4569
  renderBadgeMode(step, card, anchor, anchorSelector, host, root, doc, context, idx, design) {
4534
4570
  const trigger = step.badge?.trigger === "click" ? "click" : "hover";
4535
4571
  const placement = step.badge?.placement === "top" || step.badge?.placement === "left" || step.badge?.placement === "right" ? step.badge.placement : "bottom";
4572
+ const { host: markerHost, root: markerRoot } = this.createDetachedHost();
4536
4573
  const badge = doc.createElement("div");
4537
4574
  badge.className = "veo-composite-badge";
4538
4575
  badge.setAttribute("role", "button");
@@ -4543,7 +4580,8 @@ var init_composite_renderer = __esm({
4543
4580
  const marker = step.badge?.marker ?? null;
4544
4581
  if (marker) badge.appendChild(buildMarkerElement(doc, marker));
4545
4582
  else this.buildContent(badge, step.badge?.blocks ?? [], doc, context, idx, [], host);
4546
- root.appendChild(badge);
4583
+ markerRoot.appendChild(badge);
4584
+ host.style.display = "block";
4547
4585
  if (design.fullWidth === true) {
4548
4586
  card.style.width = "auto";
4549
4587
  card.style.maxWidth = "320px";
@@ -4558,13 +4596,13 @@ var init_composite_renderer = __esm({
4558
4596
  wrapper.appendChild(card);
4559
4597
  root.appendChild(wrapper);
4560
4598
  if (marker) {
4561
- host.style.display = "inline-block";
4562
- this.registerCleanup(attachMarker(anchor, host, marker));
4599
+ markerHost.style.display = "inline-block";
4600
+ this.registerCleanup(attachMarker(anchor, markerHost, marker));
4563
4601
  } else {
4564
- host.style.display = "inline-block";
4602
+ markerHost.style.display = "inline-block";
4565
4603
  const pos = inlinePosOf(step.inlinePosition);
4566
- insertHost(anchor, host, pos);
4567
- this.registerCleanup(keepHostAttached(host, anchorSelector, pos));
4604
+ insertHost(anchor, markerHost, pos);
4605
+ this.registerCleanup(keepHostAttached(markerHost, anchorSelector, pos));
4568
4606
  }
4569
4607
  let open = false;
4570
4608
  let stopFloat = null;
@@ -6526,10 +6564,22 @@ function isInteractiveElement(element) {
6526
6564
  }
6527
6565
  function closestInteractive(element) {
6528
6566
  try {
6529
- return element.closest(INTERACTIVE_SELECTOR);
6567
+ const bySelector = element.closest(INTERACTIVE_SELECTOR);
6568
+ if (bySelector) return bySelector;
6530
6569
  } catch {
6531
6570
  return null;
6532
6571
  }
6572
+ let current = element;
6573
+ for (let depth = 0; current && depth < 5; depth++, current = current.parentElement) {
6574
+ if (current instanceof HTMLElement) {
6575
+ try {
6576
+ const win = current.ownerDocument.defaultView;
6577
+ if (win?.getComputedStyle(current).cursor === "pointer") return current;
6578
+ } catch {
6579
+ }
6580
+ }
6581
+ }
6582
+ return null;
6533
6583
  }
6534
6584
  function elementLabelText(element, max = 120) {
6535
6585
  const clean = (raw) => (raw ?? "").replace(EMOJI_RE, "").replace(/\s+/g, " ").trim();
@@ -6569,6 +6619,15 @@ var init_interactive_elements = __esm({
6569
6619
  '[contenteditable="true"]',
6570
6620
  "[onclick]",
6571
6621
  "[data-veo-tag]",
6622
+ // Acordeones, menús desplegables, tabs y toggles de apps modernas (React/Radix):
6623
+ // el handler no está en el HTML, pero estos atributos delatan el control.
6624
+ "[aria-expanded]",
6625
+ "[aria-haspopup]",
6626
+ "[aria-controls]",
6627
+ "[aria-pressed]",
6628
+ "[aria-selected]",
6629
+ "[data-state]",
6630
+ '[tabindex]:not([tabindex="-1"])',
6572
6631
  ...INTERACTIVE_ROLES.map((r) => `[role="${r}"]`)
6573
6632
  ].join(", ");
6574
6633
  EMOJI_RE = /\p{Extended_Pictographic}|\p{Emoji_Modifier}|\u{FE0F}|\u{200D}|\u{20E3}/gu;
@@ -8908,7 +8967,7 @@ var init_detect_theme = __esm({
8908
8967
  });
8909
8968
 
8910
8969
  // src/contract/v1.ts
8911
- var SDK_VERSION = "0.0.1";
8970
+ var SDK_VERSION = "0.6.5";
8912
8971
  var DEFAULT_FLUSH_INTERVAL_MS = 5e3;
8913
8972
  var DEFAULT_FLUSH_BATCH_SIZE = 20;
8914
8973
  var DEFAULT_API_URL = "https://veo-backend-production-8c78.up.railway.app";
@@ -9457,13 +9516,23 @@ var DomListener = class {
9457
9516
  if (!this.throttle.shouldFire(target)) return;
9458
9517
  this.emit("change", target);
9459
9518
  }
9460
- /** Busca hacia arriba un ancestro "interactivo". Devuelve null si no hay ninguno. */
9519
+ /**
9520
+ * Busca hacia arriba un ancestro "interactivo". Devuelve null si no hay ninguno.
9521
+ *
9522
+ * Además de los controles nativos, reconoce los patrones de las apps modernas
9523
+ * (React/Vue/Radix), donde el handler NO está en el HTML: acordeones, menús
9524
+ * desplegables y tabs marcados con `aria-expanded`/`aria-haspopup`/`aria-controls`/
9525
+ * `aria-pressed`/`aria-selected`/`data-state`, elementos enfocables por
9526
+ * `tabindex`, y cualquier elemento cuyo cursor COMPUTADO sea `pointer` (antes
9527
+ * solo se miraba el inline, que casi nadie usa: el cursor viene por clase).
9528
+ */
9461
9529
  findMeaningfulAncestor(element) {
9462
9530
  let current = element;
9463
9531
  let depth = 0;
9464
9532
  while (current && current !== document.documentElement && depth < 5) {
9465
9533
  const tag = current.tagName.toLowerCase();
9466
- const isInteractive2 = tag === "button" || tag === "a" || tag === "input" || tag === "select" || tag === "textarea" || current.hasAttribute("data-veo-tag") || current.hasAttribute("role") || current.hasAttribute("onclick") || current instanceof HTMLElement && current.style.cursor === "pointer";
9534
+ const tabindex = current.getAttribute("tabindex");
9535
+ const isInteractive2 = tag === "button" || tag === "a" || tag === "input" || tag === "select" || tag === "textarea" || tag === "summary" || tag === "label" || current.hasAttribute("data-veo-tag") || current.hasAttribute("role") || current.hasAttribute("onclick") || current.hasAttribute("aria-expanded") || current.hasAttribute("aria-haspopup") || current.hasAttribute("aria-controls") || current.hasAttribute("aria-pressed") || current.hasAttribute("aria-selected") || current.hasAttribute("data-state") || current.hasAttribute("contenteditable") || tabindex !== null && tabindex !== "-1" || hasPointerCursor(current);
9467
9536
  if (isInteractive2) return current;
9468
9537
  current = current.parentElement;
9469
9538
  depth++;
@@ -9475,6 +9544,16 @@ var DomListener = class {
9475
9544
  this.client.track("$autocapture", payload);
9476
9545
  }
9477
9546
  };
9547
+ function hasPointerCursor(element) {
9548
+ if (!(element instanceof HTMLElement)) return false;
9549
+ if (element.style.cursor === "pointer") return true;
9550
+ try {
9551
+ const win = element.ownerDocument.defaultView;
9552
+ return win ? win.getComputedStyle(element).cursor === "pointer" : false;
9553
+ } catch {
9554
+ return false;
9555
+ }
9556
+ }
9478
9557
 
9479
9558
  // src/plugins/autocapture/index.ts
9480
9559
  function autocapturePlugin(config = {}) {
@@ -9940,6 +10019,7 @@ function stableStringify(value) {
9940
10019
  var Client = class {
9941
10020
  constructor(config) {
9942
10021
  this.config = config;
10022
+ this.version = SDK_VERSION;
9943
10023
  this.plugins = [];
9944
10024
  this.currentOrganizationId = null;
9945
10025
  this.listeners = {