veo-sdk 0.5.34 → 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-ZKWVTSTP.mjs.map → builder-3QPHB2VJ.mjs.map} +1 -1
- package/dist/builder.cjs +2271 -412
- 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-HAAT6XVN.mjs → chunk-GMXQMZ4X.mjs} +97 -10
- package/dist/chunk-GMXQMZ4X.mjs.map +1 -0
- package/dist/{chunk-IZXJA55N.mjs → chunk-N4VFMZFA.mjs} +895 -41
- package/dist/chunk-N4VFMZFA.mjs.map +1 -0
- package/dist/{chunk-W4R4XCWL.mjs → chunk-O6USA4TU.mjs} +1117 -98
- package/dist/chunk-O6USA4TU.mjs.map +1 -0
- package/dist/{guide-preview-DbEZdGBV.d.cts → guide-preview-DylsEhrg.d.cts} +98 -5
- package/dist/{guide-preview-DbEZdGBV.d.ts → guide-preview-DylsEhrg.d.ts} +98 -5
- package/dist/index.cjs +2141 -143
- 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-ZKWVTSTP.mjs +0 -5
- package/dist/chunk-HAAT6XVN.mjs.map +0 -1
- package/dist/chunk-IZXJA55N.mjs.map +0 -1
- package/dist/chunk-W4R4XCWL.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, isAutomaticActivation, activationDelayMs, 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 {
|
|
@@ -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;
|
|
@@ -836,6 +847,10 @@ var GuidesController = class {
|
|
|
836
847
|
if (this.debug) console.log(`[veo] guides: filtered locally guideId=${guide.guideId}`);
|
|
837
848
|
return;
|
|
838
849
|
}
|
|
850
|
+
if (!opts.byUser && isSnoozed(guide.guideId)) {
|
|
851
|
+
if (this.debug) console.log(`[veo] guides: snoozed guideId=${guide.guideId}`);
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
839
854
|
if (!opts.byUser && this.isHeldByRepeat(guide)) {
|
|
840
855
|
if (this.debug) console.log(`[veo] guides: held by repeat guideId=${guide.guideId}`);
|
|
841
856
|
return;
|
|
@@ -1111,6 +1126,17 @@ ${pageUrl}`;
|
|
|
1111
1126
|
const goToStep = (target) => {
|
|
1112
1127
|
cleanup();
|
|
1113
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
|
+
}
|
|
1114
1140
|
const step = steps[target];
|
|
1115
1141
|
if (step && stepMatchesPage(step.pageLocation, pageUrl)) {
|
|
1116
1142
|
this.renderCompositeStep(guide, target, sessionId, pageUrl, badgeOpen);
|
|
@@ -1135,10 +1161,15 @@ ${pageUrl}`;
|
|
|
1135
1161
|
onInteraction: (e) => this.handleInteraction(guide, sessionId, pageUrl, e),
|
|
1136
1162
|
onClose: cleanup,
|
|
1137
1163
|
onTrack: (name, props) => this.client.track(name, props),
|
|
1138
|
-
onFormSubmit: (answers) => this.submitFormResponse(guide.guideId, answers),
|
|
1164
|
+
onFormSubmit: (answers, meta) => this.submitFormResponse(guide.guideId, answers, meta),
|
|
1139
1165
|
onOpenGuide: (targetGuideId) => {
|
|
1140
1166
|
void this.openGuideById(targetGuideId, sessionId, pageUrl);
|
|
1141
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
|
+
},
|
|
1142
1173
|
// Badge: cuando el MOTOR muestra la guía (automático, elemento objetivo
|
|
1143
1174
|
// o encadenada), el contenido se abre solo; el marcador queda para
|
|
1144
1175
|
// volver a verla. Solo `manual` deja el tooltip cerrado.
|
|
@@ -1166,7 +1197,7 @@ ${pageUrl}`;
|
|
|
1166
1197
|
const onTrack = (eventName, properties) => {
|
|
1167
1198
|
this.client.track(eventName, properties);
|
|
1168
1199
|
};
|
|
1169
|
-
const onFormSubmit = (answers) => this.submitFormResponse(guide.guideId, answers);
|
|
1200
|
+
const onFormSubmit = (answers, meta) => this.submitFormResponse(guide.guideId, answers, meta);
|
|
1170
1201
|
const onOpenGuide = (targetGuideId) => {
|
|
1171
1202
|
void this.openGuideById(targetGuideId, sessionId, pageUrl);
|
|
1172
1203
|
};
|
|
@@ -1186,7 +1217,7 @@ ${pageUrl}`;
|
|
|
1186
1217
|
* un botón); respeta el dedupe de guías activas y el flujo normal de
|
|
1187
1218
|
* tracking. 404/red → no-op (la guía destino pudo borrarse).
|
|
1188
1219
|
*/
|
|
1189
|
-
async openGuideById(guideId, sessionId, pageUrl) {
|
|
1220
|
+
async openGuideById(guideId, sessionId, pageUrl, startStep) {
|
|
1190
1221
|
if (this.activeByGuideId.has(guideId)) return;
|
|
1191
1222
|
const guide = await this.resolver.fetchById(guideId);
|
|
1192
1223
|
if (!guide) {
|
|
@@ -1194,6 +1225,15 @@ ${pageUrl}`;
|
|
|
1194
1225
|
return;
|
|
1195
1226
|
}
|
|
1196
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
|
+
}
|
|
1197
1237
|
if (guide.guideType === "walkthrough" && guide.guideSteps.length > 1) {
|
|
1198
1238
|
if (!this.walkthroughState.hasActive()) {
|
|
1199
1239
|
await this.startWalkthrough(guide, endUserId, sessionId, pageUrl);
|
|
@@ -1404,6 +1444,7 @@ ${pageUrl}`;
|
|
|
1404
1444
|
console.warn("[veo] guides: interaction without endUserId \u2014 skipping enqueue");
|
|
1405
1445
|
return;
|
|
1406
1446
|
}
|
|
1447
|
+
this.noteProgress(guide.guideId, event.action, event.stepIndex);
|
|
1407
1448
|
this.trackerQueue.enqueue({
|
|
1408
1449
|
guideId: guide.guideId,
|
|
1409
1450
|
payload: {
|
|
@@ -1423,6 +1464,7 @@ ${pageUrl}`;
|
|
|
1423
1464
|
* una navegación distinta) y deduplicarlas perdería datos.
|
|
1424
1465
|
*/
|
|
1425
1466
|
enqueueInteraction(guideId, endUserId, sessionId, pageUrl, action, stepIndex) {
|
|
1467
|
+
this.noteProgress(guideId, action, stepIndex);
|
|
1426
1468
|
this.trackerQueue.enqueue({
|
|
1427
1469
|
guideId,
|
|
1428
1470
|
payload: {
|
|
@@ -1435,6 +1477,45 @@ ${pageUrl}`;
|
|
|
1435
1477
|
}
|
|
1436
1478
|
});
|
|
1437
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
|
+
}
|
|
1438
1519
|
/**
|
|
1439
1520
|
* Encola con dedup por sesión del SDK. Para `shown` del primer step:
|
|
1440
1521
|
* no queremos re-emitirlo si el usuario navega entre dos páginas que
|
|
@@ -1479,13 +1560,19 @@ ${pageUrl}`;
|
|
|
1479
1560
|
* propiedades del usuario. Usa el endUserId actual (o el anónimo si aún no
|
|
1480
1561
|
* hubo identify — el backend pre-crea la fila igual que identify).
|
|
1481
1562
|
*/
|
|
1482
|
-
async submitFormResponse(guideId, answers) {
|
|
1563
|
+
async submitFormResponse(guideId, answers, meta) {
|
|
1483
1564
|
const endUserId = this.client.getEndUserId() ?? this.client.getAnonymousId();
|
|
1484
1565
|
try {
|
|
1485
1566
|
const res = await fetch(`${this.apiUrl}/v1/guides/${guideId}/form-response`, {
|
|
1486
1567
|
method: "POST",
|
|
1487
1568
|
headers: { "Content-Type": "application/json", "X-Api-Key": this.apiKey },
|
|
1488
|
-
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
|
+
})
|
|
1489
1576
|
});
|
|
1490
1577
|
if (!res.ok && this.debug) {
|
|
1491
1578
|
console.warn("[veo] form-response respondi\xF3", res.status);
|
|
@@ -1529,5 +1616,5 @@ function guidesPlugin(config) {
|
|
|
1529
1616
|
}
|
|
1530
1617
|
|
|
1531
1618
|
export { definePlugin, guidesPlugin, runPreviewMode };
|
|
1532
|
-
//# sourceMappingURL=chunk-
|
|
1533
|
-
//# sourceMappingURL=chunk-
|
|
1619
|
+
//# sourceMappingURL=chunk-GMXQMZ4X.mjs.map
|
|
1620
|
+
//# sourceMappingURL=chunk-GMXQMZ4X.mjs.map
|