veo-sdk 0.5.33 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder-3QPHB2VJ.mjs +5 -0
- package/dist/{builder-MUTQMYAH.mjs.map → builder-3QPHB2VJ.mjs.map} +1 -1
- package/dist/builder.cjs +2470 -577
- package/dist/builder.cjs.map +1 -1
- package/dist/builder.d.cts +92 -4
- package/dist/builder.d.ts +92 -4
- package/dist/builder.mjs +4 -4
- package/dist/{chunk-FZ72JUAR.mjs → chunk-GMXQMZ4X.mjs} +123 -27
- package/dist/chunk-GMXQMZ4X.mjs.map +1 -0
- package/dist/{chunk-3ZOKCQ54.mjs → chunk-N4VFMZFA.mjs} +917 -44
- package/dist/chunk-N4VFMZFA.mjs.map +1 -0
- package/dist/{chunk-M6PB5UMW.mjs → chunk-O6USA4TU.mjs} +1133 -99
- package/dist/chunk-O6USA4TU.mjs.map +1 -0
- package/dist/{guide-preview-C73rKO0u.d.cts → guide-preview-DylsEhrg.d.cts} +109 -6
- package/dist/{guide-preview-C73rKO0u.d.ts → guide-preview-DylsEhrg.d.ts} +109 -6
- package/dist/index.cjs +2213 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +5 -5
- package/dist/veo-builder.js +261 -28
- package/dist/veo-builder.js.map +1 -1
- package/dist/veo-guides.js +228 -16
- package/dist/veo-guides.js.map +1 -1
- package/package.json +1 -1
- package/dist/builder-MUTQMYAH.mjs +0 -5
- package/dist/chunk-3ZOKCQ54.mjs.map +0 -1
- package/dist/chunk-FZ72JUAR.mjs.map +0 -1
- package/dist/chunk-M6PB5UMW.mjs.map +0 -1
package/dist/builder.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as PreviewGuideInput } from './guide-preview-
|
|
2
|
-
export { a as PreviewHandle, b as PreviewResult, c as closeGuidePreview, p as previewGuide } from './guide-preview-
|
|
1
|
+
import { P as PreviewGuideInput } from './guide-preview-DylsEhrg.cjs';
|
|
2
|
+
export { a as PreviewHandle, b as PreviewResult, c as closeGuidePreview, p as previewGuide } from './guide-preview-DylsEhrg.cjs';
|
|
3
3
|
|
|
4
4
|
/** Dónde soltó el autor un bloque nuevo. */
|
|
5
5
|
interface BlockDropPayload {
|
|
@@ -136,8 +136,14 @@ interface EditorChromeState {
|
|
|
136
136
|
presentation: 'floating' | 'inline';
|
|
137
137
|
}>;
|
|
138
138
|
activeStep: number;
|
|
139
|
-
/**
|
|
140
|
-
|
|
139
|
+
/**
|
|
140
|
+
* Qué muestra el panel. `step`, `block`, `add-block`, `row` y `structure`
|
|
141
|
+
* son vistas del paso activo (la fila de pasos lo marca); las pestañas del
|
|
142
|
+
* contenedor se «encienden» solo con `step` (contenedor) y `structure`.
|
|
143
|
+
*/
|
|
144
|
+
section: 'activation' | 'step' | 'badge' | 'target' | 'block' | 'add-block' | 'row' | 'structure';
|
|
145
|
+
/** Editando un bloque del paso: su nombre («Encuesta Texto abierto») para el título del panel. */
|
|
146
|
+
blockLabel?: string | null;
|
|
141
147
|
saving: boolean;
|
|
142
148
|
dirty: boolean;
|
|
143
149
|
/**
|
|
@@ -173,6 +179,21 @@ type PreviewStatus = {
|
|
|
173
179
|
devices: 'desktop' | 'mobile';
|
|
174
180
|
};
|
|
175
181
|
/** Acciones que el usuario dispara en el chrome (barras) y el panel ejecuta. */
|
|
182
|
+
/** Bloque de la preview: paso + id local del panel (`StepBlock.editorId`). */
|
|
183
|
+
interface BlockRef {
|
|
184
|
+
stepIndex: number;
|
|
185
|
+
blockId: string;
|
|
186
|
+
}
|
|
187
|
+
type BlockToolbarAction = 'edit' | 'duplicate' | 'remove'
|
|
188
|
+
/** Mover: arriba/abajo dentro de su columna, izquierda/derecha entre columnas de su fila. */
|
|
189
|
+
| 'move-up' | 'move-down' | 'move-left' | 'move-right';
|
|
190
|
+
/** Barra de la FILA (hover o fila del bloque seleccionado): editar / duplicar / eliminar. */
|
|
191
|
+
type RowToolbarAction = 'edit' | 'duplicate' | 'remove';
|
|
192
|
+
/** Pestañas sobre el CONTENEDOR (hover): editar el paso o abrir la estructura de filas. */
|
|
193
|
+
type CardToolbarAction = 'edit-container' | 'edit-rows';
|
|
194
|
+
type BlockLayoutAction = 'row-before' | 'row-after' | 'col-before' | 'col-after'
|
|
195
|
+
/** Bloque apilado en la MISMA celda (fila+columna), antes/después del bloque. */
|
|
196
|
+
| 'stack-before' | 'stack-after';
|
|
176
197
|
type ChromeAction = {
|
|
177
198
|
action: 'select-activation';
|
|
178
199
|
} | {
|
|
@@ -180,6 +201,14 @@ type ChromeAction = {
|
|
|
180
201
|
index: number;
|
|
181
202
|
} | {
|
|
182
203
|
action: 'add-step';
|
|
204
|
+
}
|
|
205
|
+
/** Hover sobre la tarjeta de un paso: duplicar (se inserta después) o eliminar. */
|
|
206
|
+
| {
|
|
207
|
+
action: 'duplicate-step';
|
|
208
|
+
index: number;
|
|
209
|
+
} | {
|
|
210
|
+
action: 'remove-step';
|
|
211
|
+
index: number;
|
|
183
212
|
} | {
|
|
184
213
|
action: 'save';
|
|
185
214
|
exit: boolean;
|
|
@@ -213,6 +242,47 @@ type BuilderEvent = {
|
|
|
213
242
|
} | {
|
|
214
243
|
type: 'block-dropped';
|
|
215
244
|
payload: BlockDropPayload;
|
|
245
|
+
}
|
|
246
|
+
/** Clic simple (sin arrastre) sobre la tarjeta de la preview: el panel abre «Agregar bloque». */
|
|
247
|
+
| {
|
|
248
|
+
type: 'card-clicked';
|
|
249
|
+
payload: {
|
|
250
|
+
stepIndex: number;
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/** Clic sobre un bloque de la preview: se selecciona en la app y el panel abre su editor. */
|
|
254
|
+
| {
|
|
255
|
+
type: 'block-clicked';
|
|
256
|
+
payload: BlockRef;
|
|
257
|
+
}
|
|
258
|
+
/** Barra del bloque seleccionado: editar / duplicar / eliminar. */
|
|
259
|
+
| {
|
|
260
|
+
type: 'block-action';
|
|
261
|
+
payload: BlockRef & {
|
|
262
|
+
action: BlockToolbarAction;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/** «+» en los bordes del bloque seleccionado: agregar fila arriba/abajo o columna izq/der. */
|
|
266
|
+
| {
|
|
267
|
+
type: 'block-layout';
|
|
268
|
+
payload: BlockRef & {
|
|
269
|
+
action: BlockLayoutAction;
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/** Barra de una fila: `blockId` = primer bloque de la fila (la fila no tiene id propio). */
|
|
273
|
+
| {
|
|
274
|
+
type: 'row-action';
|
|
275
|
+
payload: BlockRef & {
|
|
276
|
+
action: RowToolbarAction;
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/** Pestañas del contenedor (hover sobre la tarjeta): editar contenedor / editar filas. */
|
|
280
|
+
| {
|
|
281
|
+
type: 'card-action';
|
|
282
|
+
payload: {
|
|
283
|
+
stepIndex: number;
|
|
284
|
+
action: CardToolbarAction;
|
|
285
|
+
};
|
|
216
286
|
} | {
|
|
217
287
|
type: 'preview-status';
|
|
218
288
|
payload: PreviewStatus;
|
|
@@ -240,6 +310,16 @@ type BuilderCommand = {
|
|
|
240
310
|
label?: string;
|
|
241
311
|
} | {
|
|
242
312
|
type: 'close-preview';
|
|
313
|
+
}
|
|
314
|
+
/** El panel selecciona (o deselecciona con null) un bloque en la app. */
|
|
315
|
+
| {
|
|
316
|
+
type: 'select-block';
|
|
317
|
+
blockId: string | null;
|
|
318
|
+
}
|
|
319
|
+
/** El panel edita una fila: se marca en la app (por el id de un bloque de esa fila). */
|
|
320
|
+
| {
|
|
321
|
+
type: 'select-row';
|
|
322
|
+
blockId: string | null;
|
|
243
323
|
} | {
|
|
244
324
|
type: 'teardown';
|
|
245
325
|
} | {
|
|
@@ -248,6 +328,14 @@ type BuilderCommand = {
|
|
|
248
328
|
} | {
|
|
249
329
|
type: 'panel-visibility';
|
|
250
330
|
visible: boolean;
|
|
331
|
+
}
|
|
332
|
+
/** Tamaño compacto del panel (alto = contenido); `null` restaura el tamaño previo. */
|
|
333
|
+
| {
|
|
334
|
+
type: 'panel-size';
|
|
335
|
+
size: {
|
|
336
|
+
width: number;
|
|
337
|
+
height: number;
|
|
338
|
+
} | null;
|
|
251
339
|
} | {
|
|
252
340
|
type: 'panel-ready';
|
|
253
341
|
};
|
package/dist/builder.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as PreviewGuideInput } from './guide-preview-
|
|
2
|
-
export { a as PreviewHandle, b as PreviewResult, c as closeGuidePreview, p as previewGuide } from './guide-preview-
|
|
1
|
+
import { P as PreviewGuideInput } from './guide-preview-DylsEhrg.js';
|
|
2
|
+
export { a as PreviewHandle, b as PreviewResult, c as closeGuidePreview, p as previewGuide } from './guide-preview-DylsEhrg.js';
|
|
3
3
|
|
|
4
4
|
/** Dónde soltó el autor un bloque nuevo. */
|
|
5
5
|
interface BlockDropPayload {
|
|
@@ -136,8 +136,14 @@ interface EditorChromeState {
|
|
|
136
136
|
presentation: 'floating' | 'inline';
|
|
137
137
|
}>;
|
|
138
138
|
activeStep: number;
|
|
139
|
-
/**
|
|
140
|
-
|
|
139
|
+
/**
|
|
140
|
+
* Qué muestra el panel. `step`, `block`, `add-block`, `row` y `structure`
|
|
141
|
+
* son vistas del paso activo (la fila de pasos lo marca); las pestañas del
|
|
142
|
+
* contenedor se «encienden» solo con `step` (contenedor) y `structure`.
|
|
143
|
+
*/
|
|
144
|
+
section: 'activation' | 'step' | 'badge' | 'target' | 'block' | 'add-block' | 'row' | 'structure';
|
|
145
|
+
/** Editando un bloque del paso: su nombre («Encuesta Texto abierto») para el título del panel. */
|
|
146
|
+
blockLabel?: string | null;
|
|
141
147
|
saving: boolean;
|
|
142
148
|
dirty: boolean;
|
|
143
149
|
/**
|
|
@@ -173,6 +179,21 @@ type PreviewStatus = {
|
|
|
173
179
|
devices: 'desktop' | 'mobile';
|
|
174
180
|
};
|
|
175
181
|
/** Acciones que el usuario dispara en el chrome (barras) y el panel ejecuta. */
|
|
182
|
+
/** Bloque de la preview: paso + id local del panel (`StepBlock.editorId`). */
|
|
183
|
+
interface BlockRef {
|
|
184
|
+
stepIndex: number;
|
|
185
|
+
blockId: string;
|
|
186
|
+
}
|
|
187
|
+
type BlockToolbarAction = 'edit' | 'duplicate' | 'remove'
|
|
188
|
+
/** Mover: arriba/abajo dentro de su columna, izquierda/derecha entre columnas de su fila. */
|
|
189
|
+
| 'move-up' | 'move-down' | 'move-left' | 'move-right';
|
|
190
|
+
/** Barra de la FILA (hover o fila del bloque seleccionado): editar / duplicar / eliminar. */
|
|
191
|
+
type RowToolbarAction = 'edit' | 'duplicate' | 'remove';
|
|
192
|
+
/** Pestañas sobre el CONTENEDOR (hover): editar el paso o abrir la estructura de filas. */
|
|
193
|
+
type CardToolbarAction = 'edit-container' | 'edit-rows';
|
|
194
|
+
type BlockLayoutAction = 'row-before' | 'row-after' | 'col-before' | 'col-after'
|
|
195
|
+
/** Bloque apilado en la MISMA celda (fila+columna), antes/después del bloque. */
|
|
196
|
+
| 'stack-before' | 'stack-after';
|
|
176
197
|
type ChromeAction = {
|
|
177
198
|
action: 'select-activation';
|
|
178
199
|
} | {
|
|
@@ -180,6 +201,14 @@ type ChromeAction = {
|
|
|
180
201
|
index: number;
|
|
181
202
|
} | {
|
|
182
203
|
action: 'add-step';
|
|
204
|
+
}
|
|
205
|
+
/** Hover sobre la tarjeta de un paso: duplicar (se inserta después) o eliminar. */
|
|
206
|
+
| {
|
|
207
|
+
action: 'duplicate-step';
|
|
208
|
+
index: number;
|
|
209
|
+
} | {
|
|
210
|
+
action: 'remove-step';
|
|
211
|
+
index: number;
|
|
183
212
|
} | {
|
|
184
213
|
action: 'save';
|
|
185
214
|
exit: boolean;
|
|
@@ -213,6 +242,47 @@ type BuilderEvent = {
|
|
|
213
242
|
} | {
|
|
214
243
|
type: 'block-dropped';
|
|
215
244
|
payload: BlockDropPayload;
|
|
245
|
+
}
|
|
246
|
+
/** Clic simple (sin arrastre) sobre la tarjeta de la preview: el panel abre «Agregar bloque». */
|
|
247
|
+
| {
|
|
248
|
+
type: 'card-clicked';
|
|
249
|
+
payload: {
|
|
250
|
+
stepIndex: number;
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/** Clic sobre un bloque de la preview: se selecciona en la app y el panel abre su editor. */
|
|
254
|
+
| {
|
|
255
|
+
type: 'block-clicked';
|
|
256
|
+
payload: BlockRef;
|
|
257
|
+
}
|
|
258
|
+
/** Barra del bloque seleccionado: editar / duplicar / eliminar. */
|
|
259
|
+
| {
|
|
260
|
+
type: 'block-action';
|
|
261
|
+
payload: BlockRef & {
|
|
262
|
+
action: BlockToolbarAction;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/** «+» en los bordes del bloque seleccionado: agregar fila arriba/abajo o columna izq/der. */
|
|
266
|
+
| {
|
|
267
|
+
type: 'block-layout';
|
|
268
|
+
payload: BlockRef & {
|
|
269
|
+
action: BlockLayoutAction;
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/** Barra de una fila: `blockId` = primer bloque de la fila (la fila no tiene id propio). */
|
|
273
|
+
| {
|
|
274
|
+
type: 'row-action';
|
|
275
|
+
payload: BlockRef & {
|
|
276
|
+
action: RowToolbarAction;
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/** Pestañas del contenedor (hover sobre la tarjeta): editar contenedor / editar filas. */
|
|
280
|
+
| {
|
|
281
|
+
type: 'card-action';
|
|
282
|
+
payload: {
|
|
283
|
+
stepIndex: number;
|
|
284
|
+
action: CardToolbarAction;
|
|
285
|
+
};
|
|
216
286
|
} | {
|
|
217
287
|
type: 'preview-status';
|
|
218
288
|
payload: PreviewStatus;
|
|
@@ -240,6 +310,16 @@ type BuilderCommand = {
|
|
|
240
310
|
label?: string;
|
|
241
311
|
} | {
|
|
242
312
|
type: 'close-preview';
|
|
313
|
+
}
|
|
314
|
+
/** El panel selecciona (o deselecciona con null) un bloque en la app. */
|
|
315
|
+
| {
|
|
316
|
+
type: 'select-block';
|
|
317
|
+
blockId: string | null;
|
|
318
|
+
}
|
|
319
|
+
/** El panel edita una fila: se marca en la app (por el id de un bloque de esa fila). */
|
|
320
|
+
| {
|
|
321
|
+
type: 'select-row';
|
|
322
|
+
blockId: string | null;
|
|
243
323
|
} | {
|
|
244
324
|
type: 'teardown';
|
|
245
325
|
} | {
|
|
@@ -248,6 +328,14 @@ type BuilderCommand = {
|
|
|
248
328
|
} | {
|
|
249
329
|
type: 'panel-visibility';
|
|
250
330
|
visible: boolean;
|
|
331
|
+
}
|
|
332
|
+
/** Tamaño compacto del panel (alto = contenido); `null` restaura el tamaño previo. */
|
|
333
|
+
| {
|
|
334
|
+
type: 'panel-size';
|
|
335
|
+
size: {
|
|
336
|
+
width: number;
|
|
337
|
+
height: number;
|
|
338
|
+
} | null;
|
|
251
339
|
} | {
|
|
252
340
|
type: 'panel-ready';
|
|
253
341
|
};
|
package/dist/builder.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import './chunk-
|
|
2
|
-
import { initBuilderMode } from './chunk-
|
|
3
|
-
export { createBuilderSession, initBuilderMode, startElementPicker, stopElementPicker } from './chunk-
|
|
4
|
-
export { closeGuidePreview, previewGuide } from './chunk-
|
|
1
|
+
import './chunk-GMXQMZ4X.mjs';
|
|
2
|
+
import { initBuilderMode } from './chunk-N4VFMZFA.mjs';
|
|
3
|
+
export { createBuilderSession, initBuilderMode, startElementPicker, stopElementPicker } from './chunk-N4VFMZFA.mjs';
|
|
4
|
+
export { closeGuidePreview, previewGuide } from './chunk-O6USA4TU.mjs';
|
|
5
5
|
import './chunk-PTG3BTJE.mjs';
|
|
6
6
|
|
|
7
7
|
// src/builder.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hasDocument, hasWindow, clearPreviewToken, DEFAULT_TRACKER_MAX_RETRIES, DEFAULT_TRACKER_BATCH_SIZE, DEFAULT_TRACKER_FLUSH_INTERVAL_MS, isDeviceAllowed, stepMatchesPage, CompositeRenderer, ModalRenderer, BannerRenderer, WalkthroughRenderer, BadgeRenderer, InlineFormRenderer, FormRenderer, InlineCustomRenderer, InlineRenderer, CustomRenderer, TooltipRenderer, previewGuide, FREQUENCY_CACHE_KEY_PREFIX, FREQUENCY_CACHE_TTL_MS, FREQUENCY_CACHE_MAX_ENTRIES, WALKTHROUGH_STATE_KEY_PREFIX, WALKTHROUGH_ABANDONMENT_TIMEOUT_MS } from './chunk-
|
|
1
|
+
import { hasDocument, hasWindow, isAutomaticActivation, activationDelayMs, clearPreviewToken, DEFAULT_TRACKER_MAX_RETRIES, DEFAULT_TRACKER_BATCH_SIZE, DEFAULT_TRACKER_FLUSH_INTERVAL_MS, isDeviceAllowed, isSnoozed, stepMatchesPage, CompositeRenderer, ModalRenderer, BannerRenderer, WalkthroughRenderer, BadgeRenderer, InlineFormRenderer, FormRenderer, InlineCustomRenderer, InlineRenderer, CustomRenderer, TooltipRenderer, previewGuide, FREQUENCY_CACHE_KEY_PREFIX, FREQUENCY_CACHE_TTL_MS, FREQUENCY_CACHE_MAX_ENTRIES, WALKTHROUGH_STATE_KEY_PREFIX, WALKTHROUGH_ABANDONMENT_TIMEOUT_MS } from './chunk-O6USA4TU.mjs';
|
|
2
2
|
|
|
3
3
|
// src/plugins/plugin.ts
|
|
4
4
|
function definePlugin(plugin) {
|
|
@@ -26,7 +26,7 @@ async function runPreviewMode(opts) {
|
|
|
26
26
|
} catch (err) {
|
|
27
27
|
if (opts.debug) console.warn("[veo] preview-resolve fall\xF3:", err);
|
|
28
28
|
}
|
|
29
|
-
const submitToBackend = async (answers) => {
|
|
29
|
+
const submitToBackend = async (answers, meta) => {
|
|
30
30
|
if (!guide) return false;
|
|
31
31
|
const veo = window.veo;
|
|
32
32
|
const endUserId = veo?.getEndUserId?.() ?? veo?.getAnonymousId?.() ?? null;
|
|
@@ -35,7 +35,12 @@ async function runPreviewMode(opts) {
|
|
|
35
35
|
const res = await fetch(`${opts.apiUrl}/v1/guides/${guide.guideId}/form-response`, {
|
|
36
36
|
method: "POST",
|
|
37
37
|
headers: { "Content-Type": "application/json", "X-Api-Key": opts.apiKey },
|
|
38
|
-
body: JSON.stringify({
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
endUserId,
|
|
40
|
+
answers,
|
|
41
|
+
...meta ? { stepPosition: meta.stepIndex } : {},
|
|
42
|
+
...meta?.pollId ? { pollId: meta.pollId } : {}
|
|
43
|
+
})
|
|
39
44
|
});
|
|
40
45
|
return res.ok;
|
|
41
46
|
} catch {
|
|
@@ -81,7 +86,7 @@ async function runPreviewMode(opts) {
|
|
|
81
86
|
clearWaits();
|
|
82
87
|
const rules = guide.activationRules;
|
|
83
88
|
const selector = rules.selector?.trim();
|
|
84
|
-
if ((rules.trigger === "on_click" || rules.trigger === "on_hover") && selector) {
|
|
89
|
+
if ((rules.trigger === "on_click" || rules.trigger === "on_hover") && selector && !isAutomaticActivation(rules)) {
|
|
85
90
|
const verb = rules.trigger === "on_hover" ? "pasa el mouse por" : "haz clic en";
|
|
86
91
|
chip.setLabel(`${baseLabel} \xB7 ${verb} el elemento objetivo`);
|
|
87
92
|
const onFire = (e) => {
|
|
@@ -104,7 +109,7 @@ async function runPreviewMode(opts) {
|
|
|
104
109
|
};
|
|
105
110
|
return;
|
|
106
111
|
}
|
|
107
|
-
const delayMs = rules
|
|
112
|
+
const delayMs = activationDelayMs(rules);
|
|
108
113
|
if (delayMs > 0) {
|
|
109
114
|
chip.setLabel(`${baseLabel} \xB7 aparece en ${Math.round(delayMs / 1e3)} s`);
|
|
110
115
|
delayTimer = setTimeout(() => {
|
|
@@ -750,6 +755,12 @@ var GuidesController = class {
|
|
|
750
755
|
* en cada `checkGuides` con {@link pruneComposite}.
|
|
751
756
|
*/
|
|
752
757
|
this.activeComposite = /* @__PURE__ */ new Map();
|
|
758
|
+
/**
|
|
759
|
+
* Progreso de esta sesión, por guía: pasos vistos y completado, según las
|
|
760
|
+
* interacciones que ESTE SDK emitió (aunque el lote aún no haya viajado al
|
|
761
|
+
* backend). Se mezcla con la respuesta del backend en `fetchProgress`.
|
|
762
|
+
*/
|
|
763
|
+
this.sessionProgress = /* @__PURE__ */ new Map();
|
|
753
764
|
this.debug = config.debug === true;
|
|
754
765
|
this.apiUrl = config.apiUrl;
|
|
755
766
|
this.apiKey = config.apiKey;
|
|
@@ -814,12 +825,15 @@ var GuidesController = class {
|
|
|
814
825
|
if (this.debug) console.log(`[veo] guides: ${guides.length} eligible at ${pageUrl}`);
|
|
815
826
|
this.disarmTriggers();
|
|
816
827
|
for (const guide of guides) {
|
|
817
|
-
const
|
|
818
|
-
|
|
828
|
+
const rules = guide.activationRules;
|
|
829
|
+
const trigger = rules.trigger;
|
|
830
|
+
if ((trigger === "on_click" || trigger === "on_hover") && rules.selector) {
|
|
819
831
|
this.armInteractionTrigger(guide, endUserId, sessionId, pageUrl);
|
|
820
|
-
continue;
|
|
832
|
+
if (!isAutomaticActivation(rules)) continue;
|
|
821
833
|
}
|
|
822
|
-
await this.showGuide(guide, endUserId, sessionId, pageUrl
|
|
834
|
+
await this.showGuide(guide, endUserId, sessionId, pageUrl, {
|
|
835
|
+
badgeOpen: trigger !== "manual"
|
|
836
|
+
});
|
|
823
837
|
}
|
|
824
838
|
}
|
|
825
839
|
/**
|
|
@@ -827,12 +841,17 @@ var GuidesController = class {
|
|
|
827
841
|
* tipo). Cuerpo original del loop de `checkGuides`, extraído para que los
|
|
828
842
|
* disparadores por interacción pasen por LOS MISMOS chequeos al disparar.
|
|
829
843
|
*/
|
|
830
|
-
async showGuide(guide, endUserId, sessionId, pageUrl) {
|
|
844
|
+
async showGuide(guide, endUserId, sessionId, pageUrl, opts = {}) {
|
|
845
|
+
const badgeOpen = opts.badgeOpen !== false;
|
|
831
846
|
if (this.frequencyCache.shouldFilter(guide.guideId, guide.displayFrequency)) {
|
|
832
847
|
if (this.debug) console.log(`[veo] guides: filtered locally guideId=${guide.guideId}`);
|
|
833
848
|
return;
|
|
834
849
|
}
|
|
835
|
-
if (
|
|
850
|
+
if (!opts.byUser && isSnoozed(guide.guideId)) {
|
|
851
|
+
if (this.debug) console.log(`[veo] guides: snoozed guideId=${guide.guideId}`);
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
if (!opts.byUser && this.isHeldByRepeat(guide)) {
|
|
836
855
|
if (this.debug) console.log(`[veo] guides: held by repeat guideId=${guide.guideId}`);
|
|
837
856
|
return;
|
|
838
857
|
}
|
|
@@ -850,7 +869,7 @@ var GuidesController = class {
|
|
|
850
869
|
return;
|
|
851
870
|
}
|
|
852
871
|
if (guide.guideType === "composite") {
|
|
853
|
-
this.startComposite(guide, sessionId, pageUrl);
|
|
872
|
+
this.startComposite(guide, sessionId, pageUrl, badgeOpen);
|
|
854
873
|
return;
|
|
855
874
|
}
|
|
856
875
|
this.runSingleStepRender(guide, sessionId, pageUrl);
|
|
@@ -879,7 +898,7 @@ var GuidesController = class {
|
|
|
879
898
|
return;
|
|
880
899
|
}
|
|
881
900
|
disarm();
|
|
882
|
-
void this.showGuide(guide, endUserId, sessionId, pageUrl);
|
|
901
|
+
void this.showGuide(guide, endUserId, sessionId, pageUrl, { byUser: true });
|
|
883
902
|
};
|
|
884
903
|
const disarm = () => {
|
|
885
904
|
document.removeEventListener(eventName, onFire, true);
|
|
@@ -959,7 +978,7 @@ ${pageUrl}`;
|
|
|
959
978
|
const renderer = this.createSingleStepRenderer(guide.guideType);
|
|
960
979
|
if (!renderer) return;
|
|
961
980
|
this.activeByGuideId.set(guide.guideId, renderer);
|
|
962
|
-
const delayMs = guide.activationRules
|
|
981
|
+
const delayMs = activationDelayMs(guide.activationRules);
|
|
963
982
|
window.setTimeout(
|
|
964
983
|
() => this.mountSingleStepRenderer(guide, renderer, sessionId, pageUrl),
|
|
965
984
|
delayMs
|
|
@@ -970,23 +989,24 @@ ${pageUrl}`;
|
|
|
970
989
|
* `pageLocation` matchea la URL actual (targeting por-paso) y lo pinta con el
|
|
971
990
|
* `CompositeRenderer`. Si ningún paso aplica a esta página, no muestra nada.
|
|
972
991
|
*/
|
|
973
|
-
startComposite(guide, sessionId, pageUrl) {
|
|
992
|
+
startComposite(guide, sessionId, pageUrl, badgeOpen = true) {
|
|
974
993
|
if (this.pendingComposite?.guide.guideId === guide.guideId) return;
|
|
975
994
|
const steps = guide.guideSteps;
|
|
976
995
|
const remembered = guide.activationRules.repeat?.onLoad === "resume" ? this.recallStep(guide.guideId) : null;
|
|
977
996
|
const start = remembered !== null && stepMatchesPage(steps[remembered]?.pageLocation, pageUrl) ? remembered : steps.findIndex((s) => stepMatchesPage(s.pageLocation, pageUrl));
|
|
978
997
|
if (start === -1) return;
|
|
998
|
+
if (guide.activationRules.trigger === "manual" && !steps[start]?.badge?.enabled) return;
|
|
979
999
|
if (this.compositeDelays.has(guide.guideId)) return;
|
|
980
1000
|
this.resetDispatched(guide.guideId);
|
|
981
|
-
const delayMs = guide.activationRules
|
|
1001
|
+
const delayMs = activationDelayMs(guide.activationRules);
|
|
982
1002
|
if (delayMs <= 0) {
|
|
983
|
-
this.renderCompositeStep(guide, start, sessionId, pageUrl);
|
|
1003
|
+
this.renderCompositeStep(guide, start, sessionId, pageUrl, badgeOpen);
|
|
984
1004
|
return;
|
|
985
1005
|
}
|
|
986
1006
|
const timer = setTimeout(() => {
|
|
987
1007
|
this.compositeDelays.delete(guide.guideId);
|
|
988
1008
|
if (this.activeByGuideId.has(guide.guideId)) return;
|
|
989
|
-
this.renderCompositeStep(guide, start, sessionId, pageUrl);
|
|
1009
|
+
this.renderCompositeStep(guide, start, sessionId, pageUrl, badgeOpen);
|
|
990
1010
|
}, delayMs);
|
|
991
1011
|
this.compositeDelays.set(guide.guideId, { guide, stepIndex: start, timer });
|
|
992
1012
|
}
|
|
@@ -1088,7 +1108,7 @@ ${pageUrl}`;
|
|
|
1088
1108
|
* que los botones next/prev avancen (misma página); en single-step los
|
|
1089
1109
|
* botones cierran. Cada avance destruye el paso anterior y monta el siguiente.
|
|
1090
1110
|
*/
|
|
1091
|
-
renderCompositeStep(guide, idx, sessionId, pageUrl) {
|
|
1111
|
+
renderCompositeStep(guide, idx, sessionId, pageUrl, badgeOpen = true) {
|
|
1092
1112
|
const steps = guide.guideSteps;
|
|
1093
1113
|
this.rememberStep(guide.guideId, idx);
|
|
1094
1114
|
const renderer = new CompositeRenderer();
|
|
@@ -1106,9 +1126,20 @@ ${pageUrl}`;
|
|
|
1106
1126
|
const goToStep = (target) => {
|
|
1107
1127
|
cleanup();
|
|
1108
1128
|
if (target < 0 || target >= steps.length) return;
|
|
1129
|
+
const endUserId = this.client.getEndUserId();
|
|
1130
|
+
if (endUserId) {
|
|
1131
|
+
this.enqueueInteraction(
|
|
1132
|
+
guide.guideId,
|
|
1133
|
+
endUserId,
|
|
1134
|
+
sessionId,
|
|
1135
|
+
pageUrl,
|
|
1136
|
+
target > idx ? "step_advanced" : "step_back",
|
|
1137
|
+
target
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1109
1140
|
const step = steps[target];
|
|
1110
1141
|
if (step && stepMatchesPage(step.pageLocation, pageUrl)) {
|
|
1111
|
-
this.renderCompositeStep(guide, target, sessionId, pageUrl);
|
|
1142
|
+
this.renderCompositeStep(guide, target, sessionId, pageUrl, badgeOpen);
|
|
1112
1143
|
} else {
|
|
1113
1144
|
this.pendingComposite = { guide, stepIndex: target };
|
|
1114
1145
|
}
|
|
@@ -1130,10 +1161,19 @@ ${pageUrl}`;
|
|
|
1130
1161
|
onInteraction: (e) => this.handleInteraction(guide, sessionId, pageUrl, e),
|
|
1131
1162
|
onClose: cleanup,
|
|
1132
1163
|
onTrack: (name, props) => this.client.track(name, props),
|
|
1133
|
-
onFormSubmit: (answers) => this.submitFormResponse(guide.guideId, answers),
|
|
1164
|
+
onFormSubmit: (answers, meta) => this.submitFormResponse(guide.guideId, answers, meta),
|
|
1134
1165
|
onOpenGuide: (targetGuideId) => {
|
|
1135
1166
|
void this.openGuideById(targetGuideId, sessionId, pageUrl);
|
|
1136
1167
|
},
|
|
1168
|
+
// Lista de tareas: progreso del usuario y abrir una guía en su paso.
|
|
1169
|
+
fetchProgress: (ids) => this.fetchProgress(ids),
|
|
1170
|
+
onOpenGuideAt: (targetGuideId, stepIndex) => {
|
|
1171
|
+
void this.openGuideById(targetGuideId, sessionId, pageUrl, stepIndex);
|
|
1172
|
+
},
|
|
1173
|
+
// Badge: cuando el MOTOR muestra la guía (automático, elemento objetivo
|
|
1174
|
+
// o encadenada), el contenido se abre solo; el marcador queda para
|
|
1175
|
+
// volver a verla. Solo `manual` deja el tooltip cerrado.
|
|
1176
|
+
badgeOpen,
|
|
1137
1177
|
...nav ? { nav } : {}
|
|
1138
1178
|
});
|
|
1139
1179
|
} catch (err) {
|
|
@@ -1157,7 +1197,7 @@ ${pageUrl}`;
|
|
|
1157
1197
|
const onTrack = (eventName, properties) => {
|
|
1158
1198
|
this.client.track(eventName, properties);
|
|
1159
1199
|
};
|
|
1160
|
-
const onFormSubmit = (answers) => this.submitFormResponse(guide.guideId, answers);
|
|
1200
|
+
const onFormSubmit = (answers, meta) => this.submitFormResponse(guide.guideId, answers, meta);
|
|
1161
1201
|
const onOpenGuide = (targetGuideId) => {
|
|
1162
1202
|
void this.openGuideById(targetGuideId, sessionId, pageUrl);
|
|
1163
1203
|
};
|
|
@@ -1177,7 +1217,7 @@ ${pageUrl}`;
|
|
|
1177
1217
|
* un botón); respeta el dedupe de guías activas y el flujo normal de
|
|
1178
1218
|
* tracking. 404/red → no-op (la guía destino pudo borrarse).
|
|
1179
1219
|
*/
|
|
1180
|
-
async openGuideById(guideId, sessionId, pageUrl) {
|
|
1220
|
+
async openGuideById(guideId, sessionId, pageUrl, startStep) {
|
|
1181
1221
|
if (this.activeByGuideId.has(guideId)) return;
|
|
1182
1222
|
const guide = await this.resolver.fetchById(guideId);
|
|
1183
1223
|
if (!guide) {
|
|
@@ -1185,6 +1225,15 @@ ${pageUrl}`;
|
|
|
1185
1225
|
return;
|
|
1186
1226
|
}
|
|
1187
1227
|
const endUserId = this.client.getEndUserId() ?? this.client.getAnonymousId();
|
|
1228
|
+
if (guide.guideType === "composite" && typeof startStep === "number") {
|
|
1229
|
+
const total = guide.guideSteps.length;
|
|
1230
|
+
const idx = Math.max(0, Math.min(total - 1, Math.floor(startStep)));
|
|
1231
|
+
this.enqueueInteractionOnce(guide.guideId, endUserId, sessionId, pageUrl, "shown", 0);
|
|
1232
|
+
if (idx > 0)
|
|
1233
|
+
this.enqueueInteraction(guide.guideId, endUserId, sessionId, pageUrl, "step_advanced", idx);
|
|
1234
|
+
this.renderCompositeStep(guide, idx, sessionId, pageUrl);
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1188
1237
|
if (guide.guideType === "walkthrough" && guide.guideSteps.length > 1) {
|
|
1189
1238
|
if (!this.walkthroughState.hasActive()) {
|
|
1190
1239
|
await this.startWalkthrough(guide, endUserId, sessionId, pageUrl);
|
|
@@ -1395,6 +1444,7 @@ ${pageUrl}`;
|
|
|
1395
1444
|
console.warn("[veo] guides: interaction without endUserId \u2014 skipping enqueue");
|
|
1396
1445
|
return;
|
|
1397
1446
|
}
|
|
1447
|
+
this.noteProgress(guide.guideId, event.action, event.stepIndex);
|
|
1398
1448
|
this.trackerQueue.enqueue({
|
|
1399
1449
|
guideId: guide.guideId,
|
|
1400
1450
|
payload: {
|
|
@@ -1414,6 +1464,7 @@ ${pageUrl}`;
|
|
|
1414
1464
|
* una navegación distinta) y deduplicarlas perdería datos.
|
|
1415
1465
|
*/
|
|
1416
1466
|
enqueueInteraction(guideId, endUserId, sessionId, pageUrl, action, stepIndex) {
|
|
1467
|
+
this.noteProgress(guideId, action, stepIndex);
|
|
1417
1468
|
this.trackerQueue.enqueue({
|
|
1418
1469
|
guideId,
|
|
1419
1470
|
payload: {
|
|
@@ -1426,6 +1477,45 @@ ${pageUrl}`;
|
|
|
1426
1477
|
}
|
|
1427
1478
|
});
|
|
1428
1479
|
}
|
|
1480
|
+
noteProgress(guideId, action, stepIndex) {
|
|
1481
|
+
if (action !== "shown" && action !== "step_advanced" && action !== "step_back" && action !== "completed") {
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
const cur = this.sessionProgress.get(guideId) ?? { maxStep: -1, completed: false };
|
|
1485
|
+
this.sessionProgress.set(guideId, {
|
|
1486
|
+
maxStep: Math.max(cur.maxStep, stepIndex),
|
|
1487
|
+
completed: cur.completed || action === "completed"
|
|
1488
|
+
});
|
|
1489
|
+
}
|
|
1490
|
+
/**
|
|
1491
|
+
* Progreso del usuario en varias guías (bloque «Lista de tareas»): lo pide
|
|
1492
|
+
* al backend y lo eleva con lo visto en esta sesión (nunca lo baja).
|
|
1493
|
+
*/
|
|
1494
|
+
async fetchProgress(guideIds) {
|
|
1495
|
+
const endUserId = this.client.getEndUserId() ?? this.client.getAnonymousId();
|
|
1496
|
+
let rows = [];
|
|
1497
|
+
try {
|
|
1498
|
+
const params = new URLSearchParams({ endUserId, guideIds: guideIds.join(",") });
|
|
1499
|
+
const res = await fetch(`${this.apiUrl}/v1/guides/progress?${params}`, {
|
|
1500
|
+
headers: { "X-Api-Key": this.apiKey }
|
|
1501
|
+
});
|
|
1502
|
+
if (res.ok) rows = (await res.json()).items ?? [];
|
|
1503
|
+
else if (this.debug) console.warn("[veo] guides/progress respondi\xF3", res.status);
|
|
1504
|
+
} catch (err) {
|
|
1505
|
+
if (this.debug) console.warn("[veo] guides/progress fall\xF3:", err);
|
|
1506
|
+
}
|
|
1507
|
+
return rows.map((r) => {
|
|
1508
|
+
const local = this.sessionProgress.get(r.guideId);
|
|
1509
|
+
if (!local) return r;
|
|
1510
|
+
const seen = Math.min(r.totalSteps, local.maxStep + 1);
|
|
1511
|
+
const completed = r.completed || local.completed || seen >= r.totalSteps;
|
|
1512
|
+
return {
|
|
1513
|
+
...r,
|
|
1514
|
+
currentStep: completed ? r.totalSteps : Math.max(r.currentStep, seen),
|
|
1515
|
+
completed
|
|
1516
|
+
};
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1429
1519
|
/**
|
|
1430
1520
|
* Encola con dedup por sesión del SDK. Para `shown` del primer step:
|
|
1431
1521
|
* no queremos re-emitirlo si el usuario navega entre dos páginas que
|
|
@@ -1470,13 +1560,19 @@ ${pageUrl}`;
|
|
|
1470
1560
|
* propiedades del usuario. Usa el endUserId actual (o el anónimo si aún no
|
|
1471
1561
|
* hubo identify — el backend pre-crea la fila igual que identify).
|
|
1472
1562
|
*/
|
|
1473
|
-
async submitFormResponse(guideId, answers) {
|
|
1563
|
+
async submitFormResponse(guideId, answers, meta) {
|
|
1474
1564
|
const endUserId = this.client.getEndUserId() ?? this.client.getAnonymousId();
|
|
1475
1565
|
try {
|
|
1476
1566
|
const res = await fetch(`${this.apiUrl}/v1/guides/${guideId}/form-response`, {
|
|
1477
1567
|
method: "POST",
|
|
1478
1568
|
headers: { "Content-Type": "application/json", "X-Api-Key": this.apiKey },
|
|
1479
|
-
body: JSON.stringify({
|
|
1569
|
+
body: JSON.stringify({
|
|
1570
|
+
endUserId,
|
|
1571
|
+
answers,
|
|
1572
|
+
sessionId: this.client.getSessionId(),
|
|
1573
|
+
...meta ? { stepPosition: meta.stepIndex } : {},
|
|
1574
|
+
...meta?.pollId ? { pollId: meta.pollId } : {}
|
|
1575
|
+
})
|
|
1480
1576
|
});
|
|
1481
1577
|
if (!res.ok && this.debug) {
|
|
1482
1578
|
console.warn("[veo] form-response respondi\xF3", res.status);
|
|
@@ -1520,5 +1616,5 @@ function guidesPlugin(config) {
|
|
|
1520
1616
|
}
|
|
1521
1617
|
|
|
1522
1618
|
export { definePlugin, guidesPlugin, runPreviewMode };
|
|
1523
|
-
//# sourceMappingURL=chunk-
|
|
1524
|
-
//# sourceMappingURL=chunk-
|
|
1619
|
+
//# sourceMappingURL=chunk-GMXQMZ4X.mjs.map
|
|
1620
|
+
//# sourceMappingURL=chunk-GMXQMZ4X.mjs.map
|