@magicfeedback/popup-sdk 1.11.0 → 1.13.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/index.d.mts +41 -4
- package/dist/index.d.ts +41 -4
- package/dist/index.js +54 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +54 -13
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +23 -3
- package/dist/react-native.d.ts +23 -3
- package/dist/react-native.js +54 -13
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +54 -13
- package/dist/react-native.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -383,6 +383,23 @@ type EventListener = (event: DeepdotsEvent) => void;
|
|
|
383
383
|
* anterior se cierra y se abre otra, como hace GA con su timeout de sesión.
|
|
384
384
|
*/
|
|
385
385
|
type SessionEndReason = 'page_hide' | 'background' | 'user_change' | 'tracking_disabled' | 'manual' | 'idle_timeout';
|
|
386
|
+
/**
|
|
387
|
+
* Motivo del `deepdots_session_start` (param `reason`): por qué EMPIEZA la sesión. Permite a
|
|
388
|
+
* analytics separar una carga/arranque real de una vuelta desde background ("Started here").
|
|
389
|
+
* Mismos valores que el SDK nativo donde el significado coincide:
|
|
390
|
+
* - `cold_start`: `init()` (carga de la página / arranque de la app RN) sin sesión suspendida
|
|
391
|
+
* que reanudar. Una recarga en menos de 1 min no emite `session_start` sino
|
|
392
|
+
* `deepdots_session_resume`.
|
|
393
|
+
* - `foreground`: `onForeground()` (RN, AppState 'active') tras un cierre (`onBackground()`
|
|
394
|
+
* o `endSession()`). Con la sesión abierta no emite nada.
|
|
395
|
+
* - `tracking_enabled`: `setTrackingEnabled(true)` (consentimiento concedido).
|
|
396
|
+
* - `user_change`: `setUserId()` o un `init()` con otro `userId`, tras cerrar la del anterior.
|
|
397
|
+
* - `idle_timeout`: la pestaña vuelve a verse tras más de 30 min oculta (web): la sesión
|
|
398
|
+
* anterior se cerró (o se descartó) y empieza otra.
|
|
399
|
+
* - `bfcache_restore`: la página vuelve de la bfcache (botón atrás, `pageshow` con
|
|
400
|
+
* `persisted`) fuera de la ventana de reanudación (web).
|
|
401
|
+
*/
|
|
402
|
+
type SessionStartReason = 'cold_start' | 'foreground' | 'tracking_enabled' | 'user_change' | 'idle_timeout' | 'bfcache_restore';
|
|
386
403
|
/** Trigger type used by remote popup definitions */
|
|
387
404
|
type PopupTriggerType = 'time_on_page' | 'scroll' | 'exit' | 'click' | 'event';
|
|
388
405
|
type PopupTriggerConditionStatus = 'SHOWED' | 'PARTIAL' | 'COMPLETED';
|
|
@@ -888,8 +905,15 @@ declare class DeepdotsPopups {
|
|
|
888
905
|
*/
|
|
889
906
|
private closeSession;
|
|
890
907
|
/**
|
|
891
|
-
* Abre sesión (`session_start`) si no hay una abierta y el tracking está activo. Idempotente
|
|
892
|
-
*
|
|
908
|
+
* Abre sesión (`session_start`) si no hay una abierta y el tracking está activo. Idempotente.
|
|
909
|
+
* El `reason` dice por qué empieza (ver `SessionStartReason`):
|
|
910
|
+
* - `cold_start`: init() (carga de la página / arranque de la app RN).
|
|
911
|
+
* - `foreground`: onForeground() tras un cierre (RN).
|
|
912
|
+
* - `tracking_enabled`: setTrackingEnabled(true).
|
|
913
|
+
* - `user_change`: setUserId() o init() con otro userId.
|
|
914
|
+
* - `idle_timeout`: la pestaña vuelve a verse tras más de 30 min oculta.
|
|
915
|
+
* - `bfcache_restore`: vuelta desde la bfcache fuera de la ventana de reanudación.
|
|
916
|
+
* Si hay una sesión suspendida a tiempo emite `deepdots_session_resume` en su lugar, sin reason.
|
|
893
917
|
*/
|
|
894
918
|
private openSession;
|
|
895
919
|
/** Web: si la pestaña se ve. Sin `document` (RN) manda AppState vía onForeground/onBackground. */
|
|
@@ -905,7 +929,20 @@ declare class DeepdotsPopups {
|
|
|
905
929
|
final?: boolean;
|
|
906
930
|
sessionEnd?: boolean;
|
|
907
931
|
}): void;
|
|
908
|
-
/**
|
|
932
|
+
/**
|
|
933
|
+
* Emite un evento `user_engagement` con el tiempo activo acumulado (#8) y la pantalla en
|
|
934
|
+
* curso: `screen` y `path` (los mismos que llevará su `page_view`) y `screen_seconds` (lo
|
|
935
|
+
* que lleva en ella, medido como el `duration_seconds` del `page_view`).
|
|
936
|
+
*
|
|
937
|
+
* El `page_view` sale al SALIR de la pantalla; si el cierre no llega nunca (pestaña dormida
|
|
938
|
+
* y descartada al volver, pestaña o app matada en segundo plano), la última pantalla de la
|
|
939
|
+
* sesión se perdía y una visita de una sola pantalla se quedaba sin ninguna. Con la pantalla
|
|
940
|
+
* en el latido y en el engagement de ocultar la pestaña, el backend la reconstruye.
|
|
941
|
+
*
|
|
942
|
+
* En los cierres (`closeSession`, `suspendSession`) el observador ya emitió el `page_view`
|
|
943
|
+
* y no tiene pantalla, así que ese engagement va sin `screen`: nunca se cuenta dos veces.
|
|
944
|
+
* Tampoco se emite un `page_view` aquí, por lo mismo.
|
|
945
|
+
*/
|
|
909
946
|
private flushEngagement;
|
|
910
947
|
/** Tick del flush periódico: latido de engagement si toca, y envío de lo acumulado. */
|
|
911
948
|
private onAnalyticsFlushTick;
|
|
@@ -1362,4 +1399,4 @@ declare function collectRnDevice(d: DeviceInfoLike): DeviceInfo;
|
|
|
1362
1399
|
*/
|
|
1363
1400
|
declare function setupReactNative(sdk: DeepdotsPopups, config: DeepdotsInitParams, deps?: ReactNativeSetupDeps): () => void;
|
|
1364
1401
|
|
|
1365
|
-
export { type AnalyticsFeedbackBody, type AnalyticsKeys, type AppStateLike, BrowserPopupRenderer, type BuildBodyOptions, type ContactAttributeValue, type ContactAttributes, type ContactBody, ContactManager, type CrashRecord, CrashReporter, type CrashSeverity, type DeepdotsConfig, type DeepdotsEvent, type DeepdotsEventType, type DeepdotsInitParams, type DeepdotsLogger, DeepdotsPopups, type DeviceInfo, type DeviceInfoLike, type DeviceSnapshot, type EventListener, type FeedbackKV, type FeedbackSession, InMemoryStorage, type KeyValueStorage, LABELS, MAX_TRACKED_MESSAGES, MESSAGE_CHANNELS, type MessageChannel, MessageGuard, type MessageGuardVerdict, type MessageRejectionReason, type MessageStage, type MmkvLike, NATIVE_READY_GRACE_MS, NoopPopupRenderer, POPUP_TRIGGER_CONDITION_STATUSES, type PopupDefinition, type PopupLabels, type PopupLocale, type PopupRenderer, type PopupTrigger, type PopupTriggerCondition, type PopupTriggerConditionStatus, REVEAL_TIMEOUT_MS, RTL_LOCALES, type ReactNativeErrorUtils, ReactNativePopupRenderer, type ReactNativeRendererOptions, type ReactNativeSetupDeps, type ReactNativeSurveyPayload, type ReportErrorOptions, type ResolvedActionLabels, SUPPORTED_LANGUAGES, type SessionEndReason, type TrackMessageOptions, type TriggerConfig, buildAnalyticsFeedbackBody, buildMessageParams, buildSurveyHtml, collectRnDevice, crashRecordToParams, createDefaultRenderer, createFeedbackSink, directionFor, getLabels, isRtlLanguage, mmkvStorage, resolveActionLabels, resolveLocale, setupReactNative };
|
|
1402
|
+
export { type AnalyticsFeedbackBody, type AnalyticsKeys, type AppStateLike, BrowserPopupRenderer, type BuildBodyOptions, type ContactAttributeValue, type ContactAttributes, type ContactBody, ContactManager, type CrashRecord, CrashReporter, type CrashSeverity, type DeepdotsConfig, type DeepdotsEvent, type DeepdotsEventType, type DeepdotsInitParams, type DeepdotsLogger, DeepdotsPopups, type DeviceInfo, type DeviceInfoLike, type DeviceSnapshot, type EventListener, type FeedbackKV, type FeedbackSession, InMemoryStorage, type KeyValueStorage, LABELS, MAX_TRACKED_MESSAGES, MESSAGE_CHANNELS, type MessageChannel, MessageGuard, type MessageGuardVerdict, type MessageRejectionReason, type MessageStage, type MmkvLike, NATIVE_READY_GRACE_MS, NoopPopupRenderer, POPUP_TRIGGER_CONDITION_STATUSES, type PopupDefinition, type PopupLabels, type PopupLocale, type PopupRenderer, type PopupTrigger, type PopupTriggerCondition, type PopupTriggerConditionStatus, REVEAL_TIMEOUT_MS, RTL_LOCALES, type ReactNativeErrorUtils, ReactNativePopupRenderer, type ReactNativeRendererOptions, type ReactNativeSetupDeps, type ReactNativeSurveyPayload, type ReportErrorOptions, type ResolvedActionLabels, SUPPORTED_LANGUAGES, type SessionEndReason, type SessionStartReason, type TrackMessageOptions, type TriggerConfig, buildAnalyticsFeedbackBody, buildMessageParams, buildSurveyHtml, collectRnDevice, crashRecordToParams, createDefaultRenderer, createFeedbackSink, directionFor, getLabels, isRtlLanguage, mmkvStorage, resolveActionLabels, resolveLocale, setupReactNative };
|
package/dist/index.d.ts
CHANGED
|
@@ -383,6 +383,23 @@ type EventListener = (event: DeepdotsEvent) => void;
|
|
|
383
383
|
* anterior se cierra y se abre otra, como hace GA con su timeout de sesión.
|
|
384
384
|
*/
|
|
385
385
|
type SessionEndReason = 'page_hide' | 'background' | 'user_change' | 'tracking_disabled' | 'manual' | 'idle_timeout';
|
|
386
|
+
/**
|
|
387
|
+
* Motivo del `deepdots_session_start` (param `reason`): por qué EMPIEZA la sesión. Permite a
|
|
388
|
+
* analytics separar una carga/arranque real de una vuelta desde background ("Started here").
|
|
389
|
+
* Mismos valores que el SDK nativo donde el significado coincide:
|
|
390
|
+
* - `cold_start`: `init()` (carga de la página / arranque de la app RN) sin sesión suspendida
|
|
391
|
+
* que reanudar. Una recarga en menos de 1 min no emite `session_start` sino
|
|
392
|
+
* `deepdots_session_resume`.
|
|
393
|
+
* - `foreground`: `onForeground()` (RN, AppState 'active') tras un cierre (`onBackground()`
|
|
394
|
+
* o `endSession()`). Con la sesión abierta no emite nada.
|
|
395
|
+
* - `tracking_enabled`: `setTrackingEnabled(true)` (consentimiento concedido).
|
|
396
|
+
* - `user_change`: `setUserId()` o un `init()` con otro `userId`, tras cerrar la del anterior.
|
|
397
|
+
* - `idle_timeout`: la pestaña vuelve a verse tras más de 30 min oculta (web): la sesión
|
|
398
|
+
* anterior se cerró (o se descartó) y empieza otra.
|
|
399
|
+
* - `bfcache_restore`: la página vuelve de la bfcache (botón atrás, `pageshow` con
|
|
400
|
+
* `persisted`) fuera de la ventana de reanudación (web).
|
|
401
|
+
*/
|
|
402
|
+
type SessionStartReason = 'cold_start' | 'foreground' | 'tracking_enabled' | 'user_change' | 'idle_timeout' | 'bfcache_restore';
|
|
386
403
|
/** Trigger type used by remote popup definitions */
|
|
387
404
|
type PopupTriggerType = 'time_on_page' | 'scroll' | 'exit' | 'click' | 'event';
|
|
388
405
|
type PopupTriggerConditionStatus = 'SHOWED' | 'PARTIAL' | 'COMPLETED';
|
|
@@ -888,8 +905,15 @@ declare class DeepdotsPopups {
|
|
|
888
905
|
*/
|
|
889
906
|
private closeSession;
|
|
890
907
|
/**
|
|
891
|
-
* Abre sesión (`session_start`) si no hay una abierta y el tracking está activo. Idempotente
|
|
892
|
-
*
|
|
908
|
+
* Abre sesión (`session_start`) si no hay una abierta y el tracking está activo. Idempotente.
|
|
909
|
+
* El `reason` dice por qué empieza (ver `SessionStartReason`):
|
|
910
|
+
* - `cold_start`: init() (carga de la página / arranque de la app RN).
|
|
911
|
+
* - `foreground`: onForeground() tras un cierre (RN).
|
|
912
|
+
* - `tracking_enabled`: setTrackingEnabled(true).
|
|
913
|
+
* - `user_change`: setUserId() o init() con otro userId.
|
|
914
|
+
* - `idle_timeout`: la pestaña vuelve a verse tras más de 30 min oculta.
|
|
915
|
+
* - `bfcache_restore`: vuelta desde la bfcache fuera de la ventana de reanudación.
|
|
916
|
+
* Si hay una sesión suspendida a tiempo emite `deepdots_session_resume` en su lugar, sin reason.
|
|
893
917
|
*/
|
|
894
918
|
private openSession;
|
|
895
919
|
/** Web: si la pestaña se ve. Sin `document` (RN) manda AppState vía onForeground/onBackground. */
|
|
@@ -905,7 +929,20 @@ declare class DeepdotsPopups {
|
|
|
905
929
|
final?: boolean;
|
|
906
930
|
sessionEnd?: boolean;
|
|
907
931
|
}): void;
|
|
908
|
-
/**
|
|
932
|
+
/**
|
|
933
|
+
* Emite un evento `user_engagement` con el tiempo activo acumulado (#8) y la pantalla en
|
|
934
|
+
* curso: `screen` y `path` (los mismos que llevará su `page_view`) y `screen_seconds` (lo
|
|
935
|
+
* que lleva en ella, medido como el `duration_seconds` del `page_view`).
|
|
936
|
+
*
|
|
937
|
+
* El `page_view` sale al SALIR de la pantalla; si el cierre no llega nunca (pestaña dormida
|
|
938
|
+
* y descartada al volver, pestaña o app matada en segundo plano), la última pantalla de la
|
|
939
|
+
* sesión se perdía y una visita de una sola pantalla se quedaba sin ninguna. Con la pantalla
|
|
940
|
+
* en el latido y en el engagement de ocultar la pestaña, el backend la reconstruye.
|
|
941
|
+
*
|
|
942
|
+
* En los cierres (`closeSession`, `suspendSession`) el observador ya emitió el `page_view`
|
|
943
|
+
* y no tiene pantalla, así que ese engagement va sin `screen`: nunca se cuenta dos veces.
|
|
944
|
+
* Tampoco se emite un `page_view` aquí, por lo mismo.
|
|
945
|
+
*/
|
|
909
946
|
private flushEngagement;
|
|
910
947
|
/** Tick del flush periódico: latido de engagement si toca, y envío de lo acumulado. */
|
|
911
948
|
private onAnalyticsFlushTick;
|
|
@@ -1362,4 +1399,4 @@ declare function collectRnDevice(d: DeviceInfoLike): DeviceInfo;
|
|
|
1362
1399
|
*/
|
|
1363
1400
|
declare function setupReactNative(sdk: DeepdotsPopups, config: DeepdotsInitParams, deps?: ReactNativeSetupDeps): () => void;
|
|
1364
1401
|
|
|
1365
|
-
export { type AnalyticsFeedbackBody, type AnalyticsKeys, type AppStateLike, BrowserPopupRenderer, type BuildBodyOptions, type ContactAttributeValue, type ContactAttributes, type ContactBody, ContactManager, type CrashRecord, CrashReporter, type CrashSeverity, type DeepdotsConfig, type DeepdotsEvent, type DeepdotsEventType, type DeepdotsInitParams, type DeepdotsLogger, DeepdotsPopups, type DeviceInfo, type DeviceInfoLike, type DeviceSnapshot, type EventListener, type FeedbackKV, type FeedbackSession, InMemoryStorage, type KeyValueStorage, LABELS, MAX_TRACKED_MESSAGES, MESSAGE_CHANNELS, type MessageChannel, MessageGuard, type MessageGuardVerdict, type MessageRejectionReason, type MessageStage, type MmkvLike, NATIVE_READY_GRACE_MS, NoopPopupRenderer, POPUP_TRIGGER_CONDITION_STATUSES, type PopupDefinition, type PopupLabels, type PopupLocale, type PopupRenderer, type PopupTrigger, type PopupTriggerCondition, type PopupTriggerConditionStatus, REVEAL_TIMEOUT_MS, RTL_LOCALES, type ReactNativeErrorUtils, ReactNativePopupRenderer, type ReactNativeRendererOptions, type ReactNativeSetupDeps, type ReactNativeSurveyPayload, type ReportErrorOptions, type ResolvedActionLabels, SUPPORTED_LANGUAGES, type SessionEndReason, type TrackMessageOptions, type TriggerConfig, buildAnalyticsFeedbackBody, buildMessageParams, buildSurveyHtml, collectRnDevice, crashRecordToParams, createDefaultRenderer, createFeedbackSink, directionFor, getLabels, isRtlLanguage, mmkvStorage, resolveActionLabels, resolveLocale, setupReactNative };
|
|
1402
|
+
export { type AnalyticsFeedbackBody, type AnalyticsKeys, type AppStateLike, BrowserPopupRenderer, type BuildBodyOptions, type ContactAttributeValue, type ContactAttributes, type ContactBody, ContactManager, type CrashRecord, CrashReporter, type CrashSeverity, type DeepdotsConfig, type DeepdotsEvent, type DeepdotsEventType, type DeepdotsInitParams, type DeepdotsLogger, DeepdotsPopups, type DeviceInfo, type DeviceInfoLike, type DeviceSnapshot, type EventListener, type FeedbackKV, type FeedbackSession, InMemoryStorage, type KeyValueStorage, LABELS, MAX_TRACKED_MESSAGES, MESSAGE_CHANNELS, type MessageChannel, MessageGuard, type MessageGuardVerdict, type MessageRejectionReason, type MessageStage, type MmkvLike, NATIVE_READY_GRACE_MS, NoopPopupRenderer, POPUP_TRIGGER_CONDITION_STATUSES, type PopupDefinition, type PopupLabels, type PopupLocale, type PopupRenderer, type PopupTrigger, type PopupTriggerCondition, type PopupTriggerConditionStatus, REVEAL_TIMEOUT_MS, RTL_LOCALES, type ReactNativeErrorUtils, ReactNativePopupRenderer, type ReactNativeRendererOptions, type ReactNativeSetupDeps, type ReactNativeSurveyPayload, type ReportErrorOptions, type ResolvedActionLabels, SUPPORTED_LANGUAGES, type SessionEndReason, type SessionStartReason, type TrackMessageOptions, type TriggerConfig, buildAnalyticsFeedbackBody, buildMessageParams, buildSurveyHtml, collectRnDevice, crashRecordToParams, createDefaultRenderer, createFeedbackSink, directionFor, getLabels, isRtlLanguage, mmkvStorage, resolveActionLabels, resolveLocale, setupReactNative };
|
package/dist/index.js
CHANGED
|
@@ -7739,6 +7739,23 @@ var NavigationObserver = class {
|
|
|
7739
7739
|
if (!this.installed || this.currentScreen != null || typeof window === "undefined") return;
|
|
7740
7740
|
this.begin(window.location.href);
|
|
7741
7741
|
}
|
|
7742
|
+
/**
|
|
7743
|
+
* La pantalla en curso, sin cerrarla ni emitir nada; null si no hay (antes de `begin`, tras
|
|
7744
|
+
* `stop`/`discard`). Para que el `user_engagement` lleve la pantalla: si el cierre de la
|
|
7745
|
+
* sesión no llega nunca (pestaña dormida y descartada, app matada), la última pantalla no
|
|
7746
|
+
* tiene `page_view` y solo queda esto.
|
|
7747
|
+
*/
|
|
7748
|
+
current() {
|
|
7749
|
+
if (this.currentScreen == null) return null;
|
|
7750
|
+
return {
|
|
7751
|
+
screen: this.currentScreen,
|
|
7752
|
+
path: this.currentPath ?? this.currentScreen,
|
|
7753
|
+
seconds: this.secondsSinceEntry(this.now())
|
|
7754
|
+
};
|
|
7755
|
+
}
|
|
7756
|
+
secondsSinceEntry(at) {
|
|
7757
|
+
return Math.max(0, Math.round((at - this.entryAt) / 1e3));
|
|
7758
|
+
}
|
|
7742
7759
|
closeCurrent() {
|
|
7743
7760
|
if (this.currentScreen == null) return;
|
|
7744
7761
|
const exit = this.now();
|
|
@@ -7747,7 +7764,7 @@ var NavigationObserver = class {
|
|
|
7747
7764
|
path: this.currentPath ?? this.currentScreen,
|
|
7748
7765
|
entry: this.entryAt,
|
|
7749
7766
|
exit,
|
|
7750
|
-
durationSeconds:
|
|
7767
|
+
durationSeconds: this.secondsSinceEntry(exit)
|
|
7751
7768
|
};
|
|
7752
7769
|
this.listeners.forEach((l) => {
|
|
7753
7770
|
try {
|
|
@@ -8472,7 +8489,7 @@ var DeepdotsPopups = class {
|
|
|
8472
8489
|
this.navObserver.install();
|
|
8473
8490
|
this.engagement = new EngagementTracker();
|
|
8474
8491
|
this.setupAnalyticsFlush();
|
|
8475
|
-
this.openSession();
|
|
8492
|
+
this.openSession("cold_start");
|
|
8476
8493
|
if (resumable && this.analyticsFeedbackSessionId === resumable.sessionId) {
|
|
8477
8494
|
this.notifyFeedbackSession(resumable.sessionId, "open");
|
|
8478
8495
|
}
|
|
@@ -8530,7 +8547,7 @@ var DeepdotsPopups = class {
|
|
|
8530
8547
|
setTrackingEnabled(enabled) {
|
|
8531
8548
|
if (!enabled) this.closeSession("tracking_disabled");
|
|
8532
8549
|
this.tracking?.setTrackingEnabled(enabled);
|
|
8533
|
-
if (enabled) this.openSession();
|
|
8550
|
+
if (enabled) this.openSession("tracking_enabled");
|
|
8534
8551
|
if (enabled) this.resolveGeo();
|
|
8535
8552
|
this.log("tracking \xB7 setTrackingEnabled:", enabled, "\xB7 session_id:", this.tracking?.getSessionId() ?? null);
|
|
8536
8553
|
}
|
|
@@ -8647,7 +8664,7 @@ var DeepdotsPopups = class {
|
|
|
8647
8664
|
/** App a foreground (RN: AppState 'active'): reanuda el engagement time y abre sesión nueva. */
|
|
8648
8665
|
onForeground() {
|
|
8649
8666
|
this.engagement?.resume();
|
|
8650
|
-
this.openSession();
|
|
8667
|
+
this.openSession("foreground");
|
|
8651
8668
|
}
|
|
8652
8669
|
/**
|
|
8653
8670
|
* App a background (RN: AppState 'background'): FIN DE SESIÓN. Cierra pantalla actual
|
|
@@ -8695,7 +8712,7 @@ var DeepdotsPopups = class {
|
|
|
8695
8712
|
this.answeredSurveys.clear();
|
|
8696
8713
|
clearPopupState(storage);
|
|
8697
8714
|
this.log("tracking \xB7 user_change \xB7 user_id:", this.tracking.getUserId());
|
|
8698
|
-
this.openSession();
|
|
8715
|
+
this.openSession("user_change");
|
|
8699
8716
|
}
|
|
8700
8717
|
/**
|
|
8701
8718
|
* Cierra la sesión actual: vuelca todo lo que quedaba abierto y envía el último lote
|
|
@@ -8721,17 +8738,24 @@ var DeepdotsPopups = class {
|
|
|
8721
8738
|
this.log("tracking \xB7 session_end:", reason);
|
|
8722
8739
|
}
|
|
8723
8740
|
/**
|
|
8724
|
-
* Abre sesión (`session_start`) si no hay una abierta y el tracking está activo. Idempotente
|
|
8725
|
-
*
|
|
8741
|
+
* Abre sesión (`session_start`) si no hay una abierta y el tracking está activo. Idempotente.
|
|
8742
|
+
* El `reason` dice por qué empieza (ver `SessionStartReason`):
|
|
8743
|
+
* - `cold_start`: init() (carga de la página / arranque de la app RN).
|
|
8744
|
+
* - `foreground`: onForeground() tras un cierre (RN).
|
|
8745
|
+
* - `tracking_enabled`: setTrackingEnabled(true).
|
|
8746
|
+
* - `user_change`: setUserId() o init() con otro userId.
|
|
8747
|
+
* - `idle_timeout`: la pestaña vuelve a verse tras más de 30 min oculta.
|
|
8748
|
+
* - `bfcache_restore`: vuelta desde la bfcache fuera de la ventana de reanudación.
|
|
8749
|
+
* Si hay una sesión suspendida a tiempo emite `deepdots_session_resume` en su lugar, sin reason.
|
|
8726
8750
|
*/
|
|
8727
|
-
openSession() {
|
|
8751
|
+
openSession(reason) {
|
|
8728
8752
|
if (this.sessionOpen) return;
|
|
8729
8753
|
if (!this.tracking?.isTrackingEnabled()) return;
|
|
8730
8754
|
const suspendedMs = this.takeSuspendedSession();
|
|
8731
8755
|
this.sessionOpen = true;
|
|
8732
8756
|
this.lastEngagementAt = Date.now();
|
|
8733
8757
|
if (suspendedMs === null) {
|
|
8734
|
-
this.track("deepdots_session_start", {});
|
|
8758
|
+
this.track("deepdots_session_start", { reason });
|
|
8735
8759
|
} else {
|
|
8736
8760
|
this.track("deepdots_session_resume", { suspended_ms: suspendedMs });
|
|
8737
8761
|
this.log("tracking \xB7 session resumed after", suspendedMs, "ms:", this.analyticsFeedbackSessionId);
|
|
@@ -8761,12 +8785,29 @@ var DeepdotsPopups = class {
|
|
|
8761
8785
|
if (!this.tracking?.isTrackingEnabled()) return;
|
|
8762
8786
|
this.analytics?.flush(this.analyticsIdentity(), options);
|
|
8763
8787
|
}
|
|
8764
|
-
/**
|
|
8788
|
+
/**
|
|
8789
|
+
* Emite un evento `user_engagement` con el tiempo activo acumulado (#8) y la pantalla en
|
|
8790
|
+
* curso: `screen` y `path` (los mismos que llevará su `page_view`) y `screen_seconds` (lo
|
|
8791
|
+
* que lleva en ella, medido como el `duration_seconds` del `page_view`).
|
|
8792
|
+
*
|
|
8793
|
+
* El `page_view` sale al SALIR de la pantalla; si el cierre no llega nunca (pestaña dormida
|
|
8794
|
+
* y descartada al volver, pestaña o app matada en segundo plano), la última pantalla de la
|
|
8795
|
+
* sesión se perdía y una visita de una sola pantalla se quedaba sin ninguna. Con la pantalla
|
|
8796
|
+
* en el latido y en el engagement de ocultar la pestaña, el backend la reconstruye.
|
|
8797
|
+
*
|
|
8798
|
+
* En los cierres (`closeSession`, `suspendSession`) el observador ya emitió el `page_view`
|
|
8799
|
+
* y no tiene pantalla, así que ese engagement va sin `screen`: nunca se cuenta dos veces.
|
|
8800
|
+
* Tampoco se emite un `page_view` aquí, por lo mismo.
|
|
8801
|
+
*/
|
|
8765
8802
|
flushEngagement() {
|
|
8766
8803
|
if (!this.tracking?.isTrackingEnabled()) return;
|
|
8767
8804
|
const ms = this.engagement?.consume() ?? 0;
|
|
8768
8805
|
if (ms > 0) {
|
|
8769
|
-
this.
|
|
8806
|
+
const current = this.navObserver?.current();
|
|
8807
|
+
this.track("deepdots_user_engagement", {
|
|
8808
|
+
engagement_time_msec: ms,
|
|
8809
|
+
...current ? { screen: current.screen, path: current.path, screen_seconds: current.seconds } : {}
|
|
8810
|
+
});
|
|
8770
8811
|
this.lastEngagementAt = Date.now();
|
|
8771
8812
|
}
|
|
8772
8813
|
}
|
|
@@ -8798,7 +8839,7 @@ var DeepdotsPopups = class {
|
|
|
8798
8839
|
} else {
|
|
8799
8840
|
this.discardSession();
|
|
8800
8841
|
}
|
|
8801
|
-
this.openSession();
|
|
8842
|
+
this.openSession("idle_timeout");
|
|
8802
8843
|
}
|
|
8803
8844
|
/**
|
|
8804
8845
|
* `pagehide` en web: SUSPENDE la sesión en vez de cerrarla, porque el navegador lo lanza
|
|
@@ -8922,7 +8963,7 @@ var DeepdotsPopups = class {
|
|
|
8922
8963
|
window.addEventListener("pageshow", (event) => {
|
|
8923
8964
|
if (!event.persisted) return;
|
|
8924
8965
|
this.startAnalyticsFlushTimer();
|
|
8925
|
-
this.openSession();
|
|
8966
|
+
this.openSession("bfcache_restore");
|
|
8926
8967
|
});
|
|
8927
8968
|
document.addEventListener("visibilitychange", () => {
|
|
8928
8969
|
if (document.visibilityState === "hidden") {
|