@magicfeedback/popup-sdk 1.7.1 → 1.8.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 +41 -5
- package/dist/{chunk-WNIUIOKF.mjs → chunk-322DDMX6.mjs} +69 -1
- package/dist/chunk-322DDMX6.mjs.map +1 -0
- package/dist/{chunk-W6MPSWMS.mjs → chunk-XHR3MHJO.mjs} +69 -1
- package/dist/chunk-XHR3MHJO.mjs.map +1 -0
- package/dist/index.d.mts +103 -6
- package/dist/index.d.ts +103 -6
- package/dist/index.js +325 -32
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +203 -28
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +61 -5
- package/dist/react-native.d.ts +61 -5
- package/dist/react-native.js +338 -40
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +219 -38
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-HHQMAW3G.mjs → renderPopup-HTNVACFV.mjs} +48 -8
- package/dist/renderPopup-HTNVACFV.mjs.map +1 -0
- package/dist/{renderPopup-EWGKG53W.mjs → renderPopup-SNDPX5RX.mjs} +46 -6
- package/dist/renderPopup-SNDPX5RX.mjs.map +1 -0
- package/package.json +4 -3
- package/dist/chunk-W6MPSWMS.mjs.map +0 -1
- package/dist/chunk-WNIUIOKF.mjs.map +0 -1
- package/dist/renderPopup-EWGKG53W.mjs.map +0 -1
- package/dist/renderPopup-HHQMAW3G.mjs.map +0 -1
package/dist/react-native.d.mts
CHANGED
|
@@ -286,6 +286,11 @@ interface PopupRenderOptions {
|
|
|
286
286
|
interface PopupRenderer {
|
|
287
287
|
/** Preparar recursos si aplica */
|
|
288
288
|
init?(): void;
|
|
289
|
+
/**
|
|
290
|
+
* Traer por adelantado lo que la apertura necesitará, en idle. Opcional: solo lo implementan
|
|
291
|
+
* los renderers cuyo coste de apertura se paga delante del usuario.
|
|
292
|
+
*/
|
|
293
|
+
preload?(): void;
|
|
289
294
|
/** Mostrar popup */
|
|
290
295
|
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, renderChrome?: boolean, options?: PopupRenderOptions): void;
|
|
291
296
|
/** Ocultar popup */
|
|
@@ -533,7 +538,27 @@ declare class DeepdotsPopups {
|
|
|
533
538
|
private showDefinition;
|
|
534
539
|
private shouldShow;
|
|
535
540
|
private matchesSegmentsLang;
|
|
541
|
+
/** `segments.path`: rutas donde el popup PUEDE mostrarse. Sin lista, en todas. */
|
|
536
542
|
private matchesSegmentsPath;
|
|
543
|
+
/**
|
|
544
|
+
* `segments.excludedPaths`: rutas donde el popup NO debe mostrarse. Gana sobre
|
|
545
|
+
* `segments.path` (`path: ['/']` + `excludedPaths: ['/cart']` = en todas menos el
|
|
546
|
+
* carrito) y se aplica también cuando no hay `path` (= en todas menos las excluidas).
|
|
547
|
+
*/
|
|
548
|
+
private isPathExcluded;
|
|
549
|
+
/**
|
|
550
|
+
* Compara UN candidato de `segments.path`/`segments.excludedPaths` con la ruta
|
|
551
|
+
* actual. Mismas reglas para incluir y para excluir:
|
|
552
|
+
* - URL absoluta → href completo exacto
|
|
553
|
+
* - empieza por / → subcadena del href (así entran las rutas con hash: `/#/home`)
|
|
554
|
+
* - resto → pathname exacto
|
|
555
|
+
* Ignora entradas que no sean string: el backend puede colar un `null` en la lista
|
|
556
|
+
* y no puede tumbar la evaluación del trigger entero (mismo fallo que hubo con
|
|
557
|
+
* `segments.lang`).
|
|
558
|
+
*/
|
|
559
|
+
private matchesPathCandidate;
|
|
560
|
+
/** href + pathname normalizados de la ruta a evaluar, o null si no hay `window.location`. */
|
|
561
|
+
private resolveCurrentLocation;
|
|
537
562
|
private evaluateCooldown;
|
|
538
563
|
private evaluateLegacyCondition;
|
|
539
564
|
private hasCooldownElapsed;
|
|
@@ -652,23 +677,47 @@ interface ReactNativeRendererOptions {
|
|
|
652
677
|
onShow?: (payload: ReactNativeSurveyPayload) => void;
|
|
653
678
|
/** Se llama al cerrar el popup: desmonta el WebView. */
|
|
654
679
|
onHide?: () => void;
|
|
680
|
+
/**
|
|
681
|
+
* Se llama cuando el survey ya está pintado dentro del WebView, o pasado el techo de espera.
|
|
682
|
+
*
|
|
683
|
+
* Sirve para no enseñar un WebView en blanco: monta el WebView en cuanto llegue `onShow` (fuera
|
|
684
|
+
* de pantalla o transparente) y ábrelo al recibir `onReady`. El HTML se revela solo de todas
|
|
685
|
+
* formas, así que el host que no lo use sigue funcionando igual.
|
|
686
|
+
*/
|
|
687
|
+
onReady?: (payload: {
|
|
688
|
+
surveyId: string;
|
|
689
|
+
}) => void;
|
|
655
690
|
}
|
|
656
691
|
/**
|
|
657
692
|
* Renderer de React Native: el SDK no puede pintar componentes RN, así que entrega el
|
|
658
693
|
* HTML del survey al host (que lo monta en `react-native-webview`) y traduce los
|
|
659
694
|
* mensajes del WebView a eventos de popup del SDK (→ `POST /sdk/popups`, Messaging #18–22).
|
|
660
695
|
*
|
|
661
|
-
* Uso:
|
|
696
|
+
* Uso: monta el WebView con `onShow` y enséñalo con `onReady`, para que el usuario no vea el
|
|
697
|
+
* WebView arrancando en blanco (motor + bundle del CDN + fetch del survey).
|
|
662
698
|
* ```tsx
|
|
663
699
|
* const renderer = new ReactNativePopupRenderer({
|
|
664
|
-
* onShow: (p) => setSurvey({ ...p,
|
|
665
|
-
*
|
|
700
|
+
* onShow: (p) => setSurvey({ ...p, ready: false }),
|
|
701
|
+
* onReady: () => setSurvey((s) => (s ? { ...s, ready: true } : s)),
|
|
702
|
+
* onHide: () => setSurvey(null),
|
|
666
703
|
* });
|
|
667
704
|
* sdk.setRenderer(renderer);
|
|
668
705
|
* // …
|
|
669
|
-
*
|
|
670
|
-
*
|
|
706
|
+
* // ⚠️ Con `<Modal visible={survey.ready}>` esto NO funciona: React Native no monta los hijos
|
|
707
|
+
* // de un Modal cerrado, así que el WebView no empezaría a cargar y `ready` no llegaría nunca.
|
|
708
|
+
* // El WebView tiene que estar montado y solo invisible.
|
|
709
|
+
* {survey ? (
|
|
710
|
+
* <View style={[StyleSheet.absoluteFill, { opacity: survey.ready ? 1 : 0 }]}
|
|
711
|
+
* pointerEvents={survey.ready ? 'auto' : 'none'}>
|
|
712
|
+
* <WebView source={{ html: survey.html }}
|
|
713
|
+
* onMessage={(e) => renderer.handleMessage(e.nativeEvent.data)} />
|
|
714
|
+
* </View>
|
|
715
|
+
* ) : null}
|
|
671
716
|
* ```
|
|
717
|
+
*
|
|
718
|
+
* Quien prefiera no complicarse puede ignorar `onReady` y abrir su Modal en `onShow`: el HTML se
|
|
719
|
+
* revela solo igualmente, así que el usuario verá el contenedor del host unos cientos de ms antes
|
|
720
|
+
* que la tarjeta, pero nunca el spinner.
|
|
672
721
|
*/
|
|
673
722
|
declare class ReactNativePopupRenderer implements PopupRenderer {
|
|
674
723
|
private options;
|
|
@@ -676,10 +725,17 @@ declare class ReactNativePopupRenderer implements PopupRenderer {
|
|
|
676
725
|
private onCloseFn;
|
|
677
726
|
private currentSurveyId;
|
|
678
727
|
private partialEmitted;
|
|
728
|
+
private readyEmitted;
|
|
729
|
+
private readyTimer;
|
|
679
730
|
constructor(options?: ReactNativeRendererOptions);
|
|
680
731
|
init(): void;
|
|
681
732
|
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: EmitFn, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, renderChrome?: boolean, options?: PopupRenderOptions): void;
|
|
682
733
|
hide(): void;
|
|
734
|
+
/** Respaldo del aviso de listo por si el WebView no llega a ejecutar el HTML. */
|
|
735
|
+
private armReadyFallback;
|
|
736
|
+
private clearReadyFallback;
|
|
737
|
+
/** Idempotente: el WebView puede avisar a la vez que vence el respaldo. */
|
|
738
|
+
private emitReady;
|
|
683
739
|
/**
|
|
684
740
|
* El host la conecta al `onMessage` del WebView. Traduce los mensajes del survey a
|
|
685
741
|
* eventos del SDK: primera interacción → `popup_clicked` (PARTIAL), completado →
|
package/dist/react-native.d.ts
CHANGED
|
@@ -286,6 +286,11 @@ interface PopupRenderOptions {
|
|
|
286
286
|
interface PopupRenderer {
|
|
287
287
|
/** Preparar recursos si aplica */
|
|
288
288
|
init?(): void;
|
|
289
|
+
/**
|
|
290
|
+
* Traer por adelantado lo que la apertura necesitará, en idle. Opcional: solo lo implementan
|
|
291
|
+
* los renderers cuyo coste de apertura se paga delante del usuario.
|
|
292
|
+
*/
|
|
293
|
+
preload?(): void;
|
|
289
294
|
/** Mostrar popup */
|
|
290
295
|
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: (type: DeepdotsEventType, surveyId: string, data?: Record<string, unknown>) => void, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, renderChrome?: boolean, options?: PopupRenderOptions): void;
|
|
291
296
|
/** Ocultar popup */
|
|
@@ -533,7 +538,27 @@ declare class DeepdotsPopups {
|
|
|
533
538
|
private showDefinition;
|
|
534
539
|
private shouldShow;
|
|
535
540
|
private matchesSegmentsLang;
|
|
541
|
+
/** `segments.path`: rutas donde el popup PUEDE mostrarse. Sin lista, en todas. */
|
|
536
542
|
private matchesSegmentsPath;
|
|
543
|
+
/**
|
|
544
|
+
* `segments.excludedPaths`: rutas donde el popup NO debe mostrarse. Gana sobre
|
|
545
|
+
* `segments.path` (`path: ['/']` + `excludedPaths: ['/cart']` = en todas menos el
|
|
546
|
+
* carrito) y se aplica también cuando no hay `path` (= en todas menos las excluidas).
|
|
547
|
+
*/
|
|
548
|
+
private isPathExcluded;
|
|
549
|
+
/**
|
|
550
|
+
* Compara UN candidato de `segments.path`/`segments.excludedPaths` con la ruta
|
|
551
|
+
* actual. Mismas reglas para incluir y para excluir:
|
|
552
|
+
* - URL absoluta → href completo exacto
|
|
553
|
+
* - empieza por / → subcadena del href (así entran las rutas con hash: `/#/home`)
|
|
554
|
+
* - resto → pathname exacto
|
|
555
|
+
* Ignora entradas que no sean string: el backend puede colar un `null` en la lista
|
|
556
|
+
* y no puede tumbar la evaluación del trigger entero (mismo fallo que hubo con
|
|
557
|
+
* `segments.lang`).
|
|
558
|
+
*/
|
|
559
|
+
private matchesPathCandidate;
|
|
560
|
+
/** href + pathname normalizados de la ruta a evaluar, o null si no hay `window.location`. */
|
|
561
|
+
private resolveCurrentLocation;
|
|
537
562
|
private evaluateCooldown;
|
|
538
563
|
private evaluateLegacyCondition;
|
|
539
564
|
private hasCooldownElapsed;
|
|
@@ -652,23 +677,47 @@ interface ReactNativeRendererOptions {
|
|
|
652
677
|
onShow?: (payload: ReactNativeSurveyPayload) => void;
|
|
653
678
|
/** Se llama al cerrar el popup: desmonta el WebView. */
|
|
654
679
|
onHide?: () => void;
|
|
680
|
+
/**
|
|
681
|
+
* Se llama cuando el survey ya está pintado dentro del WebView, o pasado el techo de espera.
|
|
682
|
+
*
|
|
683
|
+
* Sirve para no enseñar un WebView en blanco: monta el WebView en cuanto llegue `onShow` (fuera
|
|
684
|
+
* de pantalla o transparente) y ábrelo al recibir `onReady`. El HTML se revela solo de todas
|
|
685
|
+
* formas, así que el host que no lo use sigue funcionando igual.
|
|
686
|
+
*/
|
|
687
|
+
onReady?: (payload: {
|
|
688
|
+
surveyId: string;
|
|
689
|
+
}) => void;
|
|
655
690
|
}
|
|
656
691
|
/**
|
|
657
692
|
* Renderer de React Native: el SDK no puede pintar componentes RN, así que entrega el
|
|
658
693
|
* HTML del survey al host (que lo monta en `react-native-webview`) y traduce los
|
|
659
694
|
* mensajes del WebView a eventos de popup del SDK (→ `POST /sdk/popups`, Messaging #18–22).
|
|
660
695
|
*
|
|
661
|
-
* Uso:
|
|
696
|
+
* Uso: monta el WebView con `onShow` y enséñalo con `onReady`, para que el usuario no vea el
|
|
697
|
+
* WebView arrancando en blanco (motor + bundle del CDN + fetch del survey).
|
|
662
698
|
* ```tsx
|
|
663
699
|
* const renderer = new ReactNativePopupRenderer({
|
|
664
|
-
* onShow: (p) => setSurvey({ ...p,
|
|
665
|
-
*
|
|
700
|
+
* onShow: (p) => setSurvey({ ...p, ready: false }),
|
|
701
|
+
* onReady: () => setSurvey((s) => (s ? { ...s, ready: true } : s)),
|
|
702
|
+
* onHide: () => setSurvey(null),
|
|
666
703
|
* });
|
|
667
704
|
* sdk.setRenderer(renderer);
|
|
668
705
|
* // …
|
|
669
|
-
*
|
|
670
|
-
*
|
|
706
|
+
* // ⚠️ Con `<Modal visible={survey.ready}>` esto NO funciona: React Native no monta los hijos
|
|
707
|
+
* // de un Modal cerrado, así que el WebView no empezaría a cargar y `ready` no llegaría nunca.
|
|
708
|
+
* // El WebView tiene que estar montado y solo invisible.
|
|
709
|
+
* {survey ? (
|
|
710
|
+
* <View style={[StyleSheet.absoluteFill, { opacity: survey.ready ? 1 : 0 }]}
|
|
711
|
+
* pointerEvents={survey.ready ? 'auto' : 'none'}>
|
|
712
|
+
* <WebView source={{ html: survey.html }}
|
|
713
|
+
* onMessage={(e) => renderer.handleMessage(e.nativeEvent.data)} />
|
|
714
|
+
* </View>
|
|
715
|
+
* ) : null}
|
|
671
716
|
* ```
|
|
717
|
+
*
|
|
718
|
+
* Quien prefiera no complicarse puede ignorar `onReady` y abrir su Modal en `onShow`: el HTML se
|
|
719
|
+
* revela solo igualmente, así que el usuario verá el contenedor del host unos cientos de ms antes
|
|
720
|
+
* que la tarjeta, pero nunca el spinner.
|
|
672
721
|
*/
|
|
673
722
|
declare class ReactNativePopupRenderer implements PopupRenderer {
|
|
674
723
|
private options;
|
|
@@ -676,10 +725,17 @@ declare class ReactNativePopupRenderer implements PopupRenderer {
|
|
|
676
725
|
private onCloseFn;
|
|
677
726
|
private currentSurveyId;
|
|
678
727
|
private partialEmitted;
|
|
728
|
+
private readyEmitted;
|
|
729
|
+
private readyTimer;
|
|
679
730
|
constructor(options?: ReactNativeRendererOptions);
|
|
680
731
|
init(): void;
|
|
681
732
|
show(surveyId: string, productId: string, actions: PopupActions | undefined, emit: EmitFn, onClose: () => void, env?: string, userId?: string, style?: PopupStyle, sessionId?: string, miniService?: string, analyticsFeedbackSessionId?: string, renderChrome?: boolean, options?: PopupRenderOptions): void;
|
|
682
733
|
hide(): void;
|
|
734
|
+
/** Respaldo del aviso de listo por si el WebView no llega a ejecutar el HTML. */
|
|
735
|
+
private armReadyFallback;
|
|
736
|
+
private clearReadyFallback;
|
|
737
|
+
/** Idempotente: el WebView puede avisar a la vez que vence el respaldo. */
|
|
738
|
+
private emitReady;
|
|
683
739
|
/**
|
|
684
740
|
* El host la conecta al `onMessage` del WebView. Traduce los mensajes del survey a
|
|
685
741
|
* eventos del SDK: primera interacción → `popup_clicked` (PARTIAL), completado →
|