@magicfeedback/popup-sdk 1.1.7 → 1.2.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/README.md +5 -0
- package/dist/index.d.mts +169 -19
- package/dist/index.d.ts +169 -19
- package/dist/index.js +312 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +308 -50
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +77 -12
- package/dist/react-native.d.ts +77 -12
- package/dist/react-native.js +309 -48
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +305 -50
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-PS3NJDUR.mjs → renderPopup-NHWJ7YSI.mjs} +7 -1
- package/dist/renderPopup-NHWJ7YSI.mjs.map +1 -0
- package/dist/{renderPopup-EZKDMLVZ.mjs → renderPopup-R53C7DB3.mjs} +7 -1
- package/dist/renderPopup-R53C7DB3.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/renderPopup-EZKDMLVZ.mjs.map +0 -1
- package/dist/renderPopup-PS3NJDUR.mjs.map +0 -1
package/dist/react-native.d.mts
CHANGED
|
@@ -86,8 +86,11 @@ interface AnalyticsEnvelope {
|
|
|
86
86
|
* Mapeo del envelope de analytics → body de `POST /sdk/feedback`.
|
|
87
87
|
*
|
|
88
88
|
* La analítica se envía como un Feedback del modelo del Surveys SDK, agrupado por una
|
|
89
|
-
* INTEGRACIÓN creada en la plataforma. Se manda en streaming con `completed:false
|
|
90
|
-
*
|
|
89
|
+
* INTEGRACIÓN creada en la plataforma. Se manda en streaming con `completed:false`; el
|
|
90
|
+
* backend cose por `sessionId` + `user_id`. El ÚLTIMO lote de una sesión (cierre de página,
|
|
91
|
+
* app a background, cambio de usuario) va con `completed:true`: cierra el registro y el
|
|
92
|
+
* siguiente lote omite el `sessionId` viejo para que el backend abra uno nuevo.
|
|
93
|
+
* `feedback.finished` se queda siempre en `false` (no es la señal de cierre acordada).
|
|
91
94
|
*
|
|
92
95
|
* Encoding:
|
|
93
96
|
* - todo va en `feedback.metadata`: contexto (user_id, session_id, platform…) + eventos
|
|
@@ -139,9 +142,11 @@ interface DeepdotsInitParams {
|
|
|
139
142
|
/** Platform used in the analytics envelope. Default is 'web'; in RN pass 'android'/'ios'. */
|
|
140
143
|
platform?: 'web' | 'android' | 'ios';
|
|
141
144
|
/**
|
|
142
|
-
* BCP-47 language tag
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
+
* BCP-47 language tag (e.g. 'es-ES') used for the analytics context AND for popup
|
|
146
|
+
* language segmentation (`segments.lang`). If omitted, the SDK auto-detects:
|
|
147
|
+
* `navigator.language` on web, or the `Intl` locale as a fallback (works in
|
|
148
|
+
* React Native with Hermes, where `navigator.language` is absent). If no source
|
|
149
|
+
* resolves a language, popups with `segments.lang` cannot be filtered and are shown.
|
|
145
150
|
*/
|
|
146
151
|
language?: string;
|
|
147
152
|
/** Injectable device info (RN: from react-native-device-info). If missing, it is derived from the browser. */
|
|
@@ -277,13 +282,16 @@ interface ReactNativeErrorUtils {
|
|
|
277
282
|
* el funnel se correlaciona por `message_id` y se agrupa por `message_title`.
|
|
278
283
|
*/
|
|
279
284
|
type MessageStage = 'delivered' | 'clicked' | 'converted';
|
|
285
|
+
/** Canales válidos. Un mensaje tiene UN canal: se valida en runtime porque el host puede no ser TS. */
|
|
286
|
+
declare const MESSAGE_CHANNELS: readonly ["push", "in_app"];
|
|
287
|
+
type MessageChannel = (typeof MESSAGE_CHANNELS)[number];
|
|
280
288
|
interface TrackMessageOptions {
|
|
281
289
|
/** Identificador del mensaje/notificación — correlaciona el funnel delivered→clicked→converted. */
|
|
282
290
|
id: string;
|
|
283
291
|
/** Título del mensaje — dimensión de agrupación de #18–22. */
|
|
284
292
|
title: string;
|
|
285
293
|
/** Canal de entrega. */
|
|
286
|
-
channel:
|
|
294
|
+
channel: MessageChannel;
|
|
287
295
|
/** Nombre de la campaña (opcional). */
|
|
288
296
|
campaign?: string;
|
|
289
297
|
/** Valor de conversión (opcional, típico en `stage: 'converted'`). */
|
|
@@ -325,14 +333,29 @@ declare class DeepdotsPopups {
|
|
|
325
333
|
private analyticsFlushTimer;
|
|
326
334
|
/** Crash & error reporting (#14–17). Null hasta init(). */
|
|
327
335
|
private crashReporter;
|
|
336
|
+
/** Protecciones del funnel de Messaging (#18–22). Vigencia de sesión: se reinicia en init(). */
|
|
337
|
+
private messageGuard;
|
|
328
338
|
/** Observador de navegación (Fase 2): emite page_view por el canal de analytics. */
|
|
329
339
|
private navObserver;
|
|
330
340
|
/** Tiempo activo (engagement time, #8). */
|
|
331
341
|
private engagement;
|
|
332
342
|
/** Atributos internos del usuario identificado → POST /sdk/popups/contact. Null si no hay userId. */
|
|
333
343
|
private contact;
|
|
344
|
+
/** Storage resuelto en init() (inyectado por el host o localStorage). Reusado al cambiar de usuario. */
|
|
345
|
+
private storage;
|
|
334
346
|
/** Marca si ya se inició la navegación manual (setScreen) — para RN sin History API. */
|
|
335
347
|
private navStarted;
|
|
348
|
+
/**
|
|
349
|
+
* `true` entre `session_start` y `session_end`. Hace idempotente tanto la apertura como
|
|
350
|
+
* el cierre (p. ej. `visibilitychange` + `pagehide` seguidos) y permite abrir una sesión
|
|
351
|
+
* nueva al volver a foreground o al conceder el consentimiento más tarde.
|
|
352
|
+
*/
|
|
353
|
+
private sessionOpen;
|
|
354
|
+
/**
|
|
355
|
+
* Idioma resuelto en init() (explícito > navigator.language > Intl). Única fuente de
|
|
356
|
+
* verdad para el context de analytics Y para la segmentación por idioma de los popups.
|
|
357
|
+
*/
|
|
358
|
+
private language;
|
|
336
359
|
/** Initialize the SDK with configuration */
|
|
337
360
|
init(config: DeepdotsInitParams): void;
|
|
338
361
|
/** User id actual (generado por el SDK o provisto por el cliente). Null si tracking off. */
|
|
@@ -371,24 +394,66 @@ declare class DeepdotsPopups {
|
|
|
371
394
|
trackFindabilityFriction(frictionTopic: string, params?: Record<string, unknown>): void;
|
|
372
395
|
/** Funnel: un paso del embudo, correlacionado por `taskId`. El backend reconstruye conversión/drop-off/tiempo. */
|
|
373
396
|
trackFunnelStep(funnel: string, step: string, taskId: string, params?: Record<string, unknown>): void;
|
|
374
|
-
/**
|
|
397
|
+
/**
|
|
398
|
+
* Messaging (#18–22): registra una etapa del funnel de una notificación (push/in-app).
|
|
399
|
+
* No-op si tracking off. El evento se descarta (con warning) si el `channel` no es válido,
|
|
400
|
+
* si ese `(message_id, stage)` ya se emitió en la sesión, o si el `message_id` ya se reportó
|
|
401
|
+
* en otro canal — ver `MessageGuard`.
|
|
402
|
+
*/
|
|
375
403
|
trackMessage(stage: MessageStage, options: TrackMessageOptions): void;
|
|
376
404
|
/**
|
|
377
405
|
* Navegación MANUAL (entornos sin History API, p. ej. React Native con React Navigation).
|
|
378
406
|
* El host la llama en cada cambio de pantalla; emite `page_view` al salir de la anterior.
|
|
379
407
|
*/
|
|
380
408
|
setScreen(name: string): void;
|
|
381
|
-
/** App a foreground (RN: AppState 'active'): reanuda el engagement time. */
|
|
409
|
+
/** App a foreground (RN: AppState 'active'): reanuda el engagement time y abre sesión nueva. */
|
|
382
410
|
onForeground(): void;
|
|
383
411
|
/**
|
|
384
|
-
* App a background (RN: AppState 'background'):
|
|
385
|
-
* mini-
|
|
412
|
+
* App a background (RN: AppState 'background'): FIN DE SESIÓN. Cierra pantalla actual
|
|
413
|
+
* (page_view), mini-services (mini_service_exit), emite engagement + `session_end` y
|
|
414
|
+
* envía el último lote con `completed:true`.
|
|
415
|
+
*
|
|
416
|
+
* Es la única señal disponible en móvil: el kill de la app (swipe) NO da callback.
|
|
386
417
|
*/
|
|
387
418
|
onBackground(): void;
|
|
419
|
+
/**
|
|
420
|
+
* Cierre EXPLÍCITO de la sesión por parte del host (logout, fin de flujo…): emite
|
|
421
|
+
* `session_end` y envía el último lote con `completed:true`.
|
|
422
|
+
*/
|
|
423
|
+
endSession(): void;
|
|
424
|
+
/**
|
|
425
|
+
* Cambio de usuario (login / logout / cambio de cuenta). Cierra la sesión del usuario
|
|
426
|
+
* anterior (`session_end` con `reason: 'user_change'` + `completed:true`), cambia la
|
|
427
|
+
* identidad y abre una sesión nueva. Sin `userId` vuelve al id anónimo del SDK.
|
|
428
|
+
*
|
|
429
|
+
* Equivale a llamar a `init()` otra vez con otro `userId`.
|
|
430
|
+
*/
|
|
431
|
+
setUserId(userId?: string): void;
|
|
432
|
+
/**
|
|
433
|
+
* Cierra la sesión actual: vuelca todo lo que quedaba abierto y envía el último lote
|
|
434
|
+
* marcado con `completed:true`, para que el backend cierre el registro. El `sessionId`
|
|
435
|
+
* cacheado se olvida → el lote siguiente abre un registro nuevo.
|
|
436
|
+
*
|
|
437
|
+
* Idempotente: dos cierres seguidos (p. ej. `visibilitychange` + `pagehide`) no duplican
|
|
438
|
+
* el `session_end`.
|
|
439
|
+
*/
|
|
440
|
+
private closeSession;
|
|
441
|
+
/**
|
|
442
|
+
* Abre sesión (`session_start`) si no hay una abierta y el tracking está activo. Idempotente:
|
|
443
|
+
* se llama en init(), al volver a foreground y al conceder el consentimiento.
|
|
444
|
+
*/
|
|
445
|
+
private openSession;
|
|
388
446
|
/** Payload que se ENVIARÍA al endpoint de analytics (no envía ni vacía el buffer). */
|
|
389
447
|
previewAnalytics(): AnalyticsEnvelope;
|
|
390
|
-
/**
|
|
391
|
-
|
|
448
|
+
/**
|
|
449
|
+
* Envía el lote acumulado de analytics y vacía el buffer.
|
|
450
|
+
* `final: true` (cierre de página/app) cambia el transporte a `sendBeacon`, que sobrevive
|
|
451
|
+
* al unload; un lote que falle por red o 5xx se re-encola para el siguiente flush.
|
|
452
|
+
*/
|
|
453
|
+
flushAnalytics(options?: {
|
|
454
|
+
final?: boolean;
|
|
455
|
+
sessionEnd?: boolean;
|
|
456
|
+
}): void;
|
|
392
457
|
/** Emite un evento `user_engagement` con el tiempo activo acumulado (#8). */
|
|
393
458
|
private flushEngagement;
|
|
394
459
|
private analyticsIdentity;
|
package/dist/react-native.d.ts
CHANGED
|
@@ -86,8 +86,11 @@ interface AnalyticsEnvelope {
|
|
|
86
86
|
* Mapeo del envelope de analytics → body de `POST /sdk/feedback`.
|
|
87
87
|
*
|
|
88
88
|
* La analítica se envía como un Feedback del modelo del Surveys SDK, agrupado por una
|
|
89
|
-
* INTEGRACIÓN creada en la plataforma. Se manda en streaming con `completed:false
|
|
90
|
-
*
|
|
89
|
+
* INTEGRACIÓN creada en la plataforma. Se manda en streaming con `completed:false`; el
|
|
90
|
+
* backend cose por `sessionId` + `user_id`. El ÚLTIMO lote de una sesión (cierre de página,
|
|
91
|
+
* app a background, cambio de usuario) va con `completed:true`: cierra el registro y el
|
|
92
|
+
* siguiente lote omite el `sessionId` viejo para que el backend abra uno nuevo.
|
|
93
|
+
* `feedback.finished` se queda siempre en `false` (no es la señal de cierre acordada).
|
|
91
94
|
*
|
|
92
95
|
* Encoding:
|
|
93
96
|
* - todo va en `feedback.metadata`: contexto (user_id, session_id, platform…) + eventos
|
|
@@ -139,9 +142,11 @@ interface DeepdotsInitParams {
|
|
|
139
142
|
/** Platform used in the analytics envelope. Default is 'web'; in RN pass 'android'/'ios'. */
|
|
140
143
|
platform?: 'web' | 'android' | 'ios';
|
|
141
144
|
/**
|
|
142
|
-
* BCP-47 language tag
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
+
* BCP-47 language tag (e.g. 'es-ES') used for the analytics context AND for popup
|
|
146
|
+
* language segmentation (`segments.lang`). If omitted, the SDK auto-detects:
|
|
147
|
+
* `navigator.language` on web, or the `Intl` locale as a fallback (works in
|
|
148
|
+
* React Native with Hermes, where `navigator.language` is absent). If no source
|
|
149
|
+
* resolves a language, popups with `segments.lang` cannot be filtered and are shown.
|
|
145
150
|
*/
|
|
146
151
|
language?: string;
|
|
147
152
|
/** Injectable device info (RN: from react-native-device-info). If missing, it is derived from the browser. */
|
|
@@ -277,13 +282,16 @@ interface ReactNativeErrorUtils {
|
|
|
277
282
|
* el funnel se correlaciona por `message_id` y se agrupa por `message_title`.
|
|
278
283
|
*/
|
|
279
284
|
type MessageStage = 'delivered' | 'clicked' | 'converted';
|
|
285
|
+
/** Canales válidos. Un mensaje tiene UN canal: se valida en runtime porque el host puede no ser TS. */
|
|
286
|
+
declare const MESSAGE_CHANNELS: readonly ["push", "in_app"];
|
|
287
|
+
type MessageChannel = (typeof MESSAGE_CHANNELS)[number];
|
|
280
288
|
interface TrackMessageOptions {
|
|
281
289
|
/** Identificador del mensaje/notificación — correlaciona el funnel delivered→clicked→converted. */
|
|
282
290
|
id: string;
|
|
283
291
|
/** Título del mensaje — dimensión de agrupación de #18–22. */
|
|
284
292
|
title: string;
|
|
285
293
|
/** Canal de entrega. */
|
|
286
|
-
channel:
|
|
294
|
+
channel: MessageChannel;
|
|
287
295
|
/** Nombre de la campaña (opcional). */
|
|
288
296
|
campaign?: string;
|
|
289
297
|
/** Valor de conversión (opcional, típico en `stage: 'converted'`). */
|
|
@@ -325,14 +333,29 @@ declare class DeepdotsPopups {
|
|
|
325
333
|
private analyticsFlushTimer;
|
|
326
334
|
/** Crash & error reporting (#14–17). Null hasta init(). */
|
|
327
335
|
private crashReporter;
|
|
336
|
+
/** Protecciones del funnel de Messaging (#18–22). Vigencia de sesión: se reinicia en init(). */
|
|
337
|
+
private messageGuard;
|
|
328
338
|
/** Observador de navegación (Fase 2): emite page_view por el canal de analytics. */
|
|
329
339
|
private navObserver;
|
|
330
340
|
/** Tiempo activo (engagement time, #8). */
|
|
331
341
|
private engagement;
|
|
332
342
|
/** Atributos internos del usuario identificado → POST /sdk/popups/contact. Null si no hay userId. */
|
|
333
343
|
private contact;
|
|
344
|
+
/** Storage resuelto en init() (inyectado por el host o localStorage). Reusado al cambiar de usuario. */
|
|
345
|
+
private storage;
|
|
334
346
|
/** Marca si ya se inició la navegación manual (setScreen) — para RN sin History API. */
|
|
335
347
|
private navStarted;
|
|
348
|
+
/**
|
|
349
|
+
* `true` entre `session_start` y `session_end`. Hace idempotente tanto la apertura como
|
|
350
|
+
* el cierre (p. ej. `visibilitychange` + `pagehide` seguidos) y permite abrir una sesión
|
|
351
|
+
* nueva al volver a foreground o al conceder el consentimiento más tarde.
|
|
352
|
+
*/
|
|
353
|
+
private sessionOpen;
|
|
354
|
+
/**
|
|
355
|
+
* Idioma resuelto en init() (explícito > navigator.language > Intl). Única fuente de
|
|
356
|
+
* verdad para el context de analytics Y para la segmentación por idioma de los popups.
|
|
357
|
+
*/
|
|
358
|
+
private language;
|
|
336
359
|
/** Initialize the SDK with configuration */
|
|
337
360
|
init(config: DeepdotsInitParams): void;
|
|
338
361
|
/** User id actual (generado por el SDK o provisto por el cliente). Null si tracking off. */
|
|
@@ -371,24 +394,66 @@ declare class DeepdotsPopups {
|
|
|
371
394
|
trackFindabilityFriction(frictionTopic: string, params?: Record<string, unknown>): void;
|
|
372
395
|
/** Funnel: un paso del embudo, correlacionado por `taskId`. El backend reconstruye conversión/drop-off/tiempo. */
|
|
373
396
|
trackFunnelStep(funnel: string, step: string, taskId: string, params?: Record<string, unknown>): void;
|
|
374
|
-
/**
|
|
397
|
+
/**
|
|
398
|
+
* Messaging (#18–22): registra una etapa del funnel de una notificación (push/in-app).
|
|
399
|
+
* No-op si tracking off. El evento se descarta (con warning) si el `channel` no es válido,
|
|
400
|
+
* si ese `(message_id, stage)` ya se emitió en la sesión, o si el `message_id` ya se reportó
|
|
401
|
+
* en otro canal — ver `MessageGuard`.
|
|
402
|
+
*/
|
|
375
403
|
trackMessage(stage: MessageStage, options: TrackMessageOptions): void;
|
|
376
404
|
/**
|
|
377
405
|
* Navegación MANUAL (entornos sin History API, p. ej. React Native con React Navigation).
|
|
378
406
|
* El host la llama en cada cambio de pantalla; emite `page_view` al salir de la anterior.
|
|
379
407
|
*/
|
|
380
408
|
setScreen(name: string): void;
|
|
381
|
-
/** App a foreground (RN: AppState 'active'): reanuda el engagement time. */
|
|
409
|
+
/** App a foreground (RN: AppState 'active'): reanuda el engagement time y abre sesión nueva. */
|
|
382
410
|
onForeground(): void;
|
|
383
411
|
/**
|
|
384
|
-
* App a background (RN: AppState 'background'):
|
|
385
|
-
* mini-
|
|
412
|
+
* App a background (RN: AppState 'background'): FIN DE SESIÓN. Cierra pantalla actual
|
|
413
|
+
* (page_view), mini-services (mini_service_exit), emite engagement + `session_end` y
|
|
414
|
+
* envía el último lote con `completed:true`.
|
|
415
|
+
*
|
|
416
|
+
* Es la única señal disponible en móvil: el kill de la app (swipe) NO da callback.
|
|
386
417
|
*/
|
|
387
418
|
onBackground(): void;
|
|
419
|
+
/**
|
|
420
|
+
* Cierre EXPLÍCITO de la sesión por parte del host (logout, fin de flujo…): emite
|
|
421
|
+
* `session_end` y envía el último lote con `completed:true`.
|
|
422
|
+
*/
|
|
423
|
+
endSession(): void;
|
|
424
|
+
/**
|
|
425
|
+
* Cambio de usuario (login / logout / cambio de cuenta). Cierra la sesión del usuario
|
|
426
|
+
* anterior (`session_end` con `reason: 'user_change'` + `completed:true`), cambia la
|
|
427
|
+
* identidad y abre una sesión nueva. Sin `userId` vuelve al id anónimo del SDK.
|
|
428
|
+
*
|
|
429
|
+
* Equivale a llamar a `init()` otra vez con otro `userId`.
|
|
430
|
+
*/
|
|
431
|
+
setUserId(userId?: string): void;
|
|
432
|
+
/**
|
|
433
|
+
* Cierra la sesión actual: vuelca todo lo que quedaba abierto y envía el último lote
|
|
434
|
+
* marcado con `completed:true`, para que el backend cierre el registro. El `sessionId`
|
|
435
|
+
* cacheado se olvida → el lote siguiente abre un registro nuevo.
|
|
436
|
+
*
|
|
437
|
+
* Idempotente: dos cierres seguidos (p. ej. `visibilitychange` + `pagehide`) no duplican
|
|
438
|
+
* el `session_end`.
|
|
439
|
+
*/
|
|
440
|
+
private closeSession;
|
|
441
|
+
/**
|
|
442
|
+
* Abre sesión (`session_start`) si no hay una abierta y el tracking está activo. Idempotente:
|
|
443
|
+
* se llama en init(), al volver a foreground y al conceder el consentimiento.
|
|
444
|
+
*/
|
|
445
|
+
private openSession;
|
|
388
446
|
/** Payload que se ENVIARÍA al endpoint de analytics (no envía ni vacía el buffer). */
|
|
389
447
|
previewAnalytics(): AnalyticsEnvelope;
|
|
390
|
-
/**
|
|
391
|
-
|
|
448
|
+
/**
|
|
449
|
+
* Envía el lote acumulado de analytics y vacía el buffer.
|
|
450
|
+
* `final: true` (cierre de página/app) cambia el transporte a `sendBeacon`, que sobrevive
|
|
451
|
+
* al unload; un lote que falle por red o 5xx se re-encola para el siguiente flush.
|
|
452
|
+
*/
|
|
453
|
+
flushAnalytics(options?: {
|
|
454
|
+
final?: boolean;
|
|
455
|
+
sessionEnd?: boolean;
|
|
456
|
+
}): void;
|
|
392
457
|
/** Emite un evento `user_engagement` con el tiempo activo acumulado (#8). */
|
|
393
458
|
private flushEngagement;
|
|
394
459
|
private analyticsIdentity;
|