@magicfeedback/popup-sdk 1.8.5 → 1.10.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.
@@ -18,7 +18,7 @@ import {
18
18
  sdkWarn,
19
19
  setLogger,
20
20
  style_default
21
- } from "./chunk-EBJZDVC6.mjs";
21
+ } from "./chunk-TSORXOQG.mjs";
22
22
 
23
23
  // src/react-native/index.tsx
24
24
  import { createContext, useContext, useEffect, useRef, useState } from "react";
@@ -256,7 +256,7 @@ function trimmedOrNull(value) {
256
256
  }
257
257
  function buildSurveyHtml(opts) {
258
258
  const env = opts.env === "development" ? "dev" : "prod";
259
- const version = opts.version ?? "2.2.22";
259
+ const version = opts.version ?? "2.2.31";
260
260
  const cdn = `https://cdn.jsdelivr.net/npm/@magicfeedback/native@${version}/dist/magicfeedback-sdk.browser.js`;
261
261
  const sid = jsonForScript(opts.surveyId);
262
262
  const pid = jsonForScript(opts.productId);
@@ -636,10 +636,15 @@ ${REVEAL_JS}
636
636
  // textContent, as\xED que el mensaje de la plataforma (HTML con imagen) no se ver\xEDa, y su
637
637
  // fallback es un literal gen\xE9rico que ignora style.successMessage.
638
638
  addSuccessScreen:false,
639
+ // Surveys multi-idioma: native pide a la API este idioma (el del init o el del
640
+ // dispositivo); si el survey no lo tiene, la API sirve el idioma por defecto.
641
+ lang:${initLangJson}||undefined,
639
642
  onLoadedEvent:function(args){
640
- // Idioma del survey: manda sobre el del init para que el chrome no se quede en
641
- // ingl\xE9s delante de un survey traducido.
642
- var langs=args && args.formData ? args.formData.lang : null;
643
+ // Idioma en el que native muestra el survey: manda sobre el del init para que el
644
+ // chrome no se quede en ingl\xE9s delante de un survey traducido. Native < 2.3 no lo
645
+ // env\xEDa: entonces el primero de formData.lang (el idioma por defecto).
646
+ var shown=args && typeof args.lang==='string' && args.lang.trim() ? args.lang : null;
647
+ var langs=shown ? [shown] : (args && args.formData ? args.formData.lang : null);
643
648
  if(langs && langs.length){
644
649
  for(var li=0;li<langs.length;li++){
645
650
  if(typeof langs[li]==='string' && langs[li].trim()){ ddApplyLabels(langs[li]); break; }
@@ -870,7 +875,7 @@ function createReactNativeRenderer() {
870
875
  }
871
876
 
872
877
  // src/ui/preload.ts
873
- var defaultLoader = () => import("./renderPopup-E2OLIXIQ.mjs");
878
+ var defaultLoader = () => import("./renderPopup-WLOFOCDR.mjs");
874
879
  var pending = null;
875
880
  function preloadRenderPopup(loader = defaultLoader) {
876
881
  if (pending) return pending;
@@ -943,7 +948,7 @@ var BrowserPopupRenderer = class {
943
948
  if (!this.container) return;
944
949
  this.visible = true;
945
950
  const container = this.container;
946
- void import("./renderPopup-E2OLIXIQ.mjs").then(({ renderPopup }) => {
951
+ void import("./renderPopup-WLOFOCDR.mjs").then(({ renderPopup }) => {
947
952
  renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId, options);
948
953
  });
949
954
  }
@@ -1220,8 +1225,10 @@ async function safeBodyText(res) {
1220
1225
  function createFeedbackSink(options) {
1221
1226
  let feedbackSessionId;
1222
1227
  let firstPostInFlight = null;
1228
+ let generation = 0;
1223
1229
  const url = `${options.baseUrl}/sdk/feedback`;
1224
1230
  const post = async (body, final, sessionEnd = false) => {
1231
+ const postGeneration = generation;
1225
1232
  const json = JSON.stringify(body);
1226
1233
  const small = json.length <= KEEPALIVE_MAX_BYTES;
1227
1234
  if (final) options.log?.("[DeepdotsAnalytics] final flush via fetch keepalive");
@@ -1251,9 +1258,25 @@ function createFeedbackSink(options) {
1251
1258
  );
1252
1259
  return;
1253
1260
  }
1254
- if (sessionEnd) return;
1261
+ if (sessionEnd) {
1262
+ let closedId = body.sessionId;
1263
+ try {
1264
+ const data = await res.json();
1265
+ closedId = data?.sessionId ?? closedId;
1266
+ } catch {
1267
+ }
1268
+ try {
1269
+ if (closedId) options.onSessionClosed?.(closedId);
1270
+ } catch {
1271
+ }
1272
+ return;
1273
+ }
1255
1274
  try {
1256
1275
  const data = await res.json();
1276
+ if (postGeneration !== generation) {
1277
+ options.log?.("[DeepdotsAnalytics] sessionId of a closed session ignored:", data?.sessionId);
1278
+ return;
1279
+ }
1257
1280
  if (data?.sessionId && data.sessionId !== feedbackSessionId) {
1258
1281
  feedbackSessionId = data.sessionId;
1259
1282
  options.log?.("[DeepdotsAnalytics] feedbackSessionId cached:", feedbackSessionId);
@@ -1266,6 +1289,7 @@ function createFeedbackSink(options) {
1266
1289
  if (meta?.resetSession) {
1267
1290
  feedbackSessionId = void 0;
1268
1291
  firstPostInFlight = null;
1292
+ generation++;
1269
1293
  options.onSessionReset?.();
1270
1294
  return;
1271
1295
  }
@@ -1280,6 +1304,7 @@ function createFeedbackSink(options) {
1280
1304
  if (sessionEnd) {
1281
1305
  feedbackSessionId = void 0;
1282
1306
  firstPostInFlight = null;
1307
+ generation++;
1283
1308
  options.onSessionReset?.();
1284
1309
  } else if (!feedbackSessionId) {
1285
1310
  firstPostInFlight = sent.then(
@@ -1926,6 +1951,8 @@ var DeepdotsPopups = class {
1926
1951
  this.analytics = null;
1927
1952
  /** feedbackSessionId cacheado del canal de analytics (devuelto por POST /sdk/feedback). */
1928
1953
  this.analyticsFeedbackSessionId = void 0;
1954
+ /** `init({ onFeedbackSession })`: avisa al host al abrir y cerrar cada registro. */
1955
+ this.onFeedbackSession = void 0;
1929
1956
  /** Timer del flush periódico de analytics (cada ANALYTICS_FLUSH_INTERVAL_MS). */
1930
1957
  this.analyticsFlushTimer = void 0;
1931
1958
  /** Crash & error reporting (#14–17). Null hasta init(). */
@@ -1983,6 +2010,7 @@ var DeepdotsPopups = class {
1983
2010
  this.renderChrome = config.renderChrome ?? true;
1984
2011
  this.showProgressBar = config.showProgressBar;
1985
2012
  this.surveyCss = config.surveyCss;
2013
+ this.onFeedbackSession = config.onFeedbackSession;
1986
2014
  this.config = {
1987
2015
  apiKey: config.apiKey || void 0,
1988
2016
  debug: config.debug || false,
@@ -2016,7 +2044,9 @@ var DeepdotsPopups = class {
2016
2044
  log: (...a) => this.log(...a),
2017
2045
  onSessionId: (id) => {
2018
2046
  this.analyticsFeedbackSessionId = id;
2047
+ this.notifyFeedbackSession(id, "open");
2019
2048
  },
2049
+ onSessionClosed: (id) => this.notifyFeedbackSession(id, "closed"),
2020
2050
  onSessionReset: () => {
2021
2051
  this.analyticsFeedbackSessionId = void 0;
2022
2052
  }
@@ -2091,6 +2121,23 @@ var DeepdotsPopups = class {
2091
2121
  getSessionId() {
2092
2122
  return this.tracking?.getSessionId() ?? null;
2093
2123
  }
2124
+ /**
2125
+ * Id del registro de analytics abierto: el `sessionId` que devolvió `POST /sdk/feedback`,
2126
+ * que la API guarda como `sdkSessionId` en el Feedback en que se convierte la sesión. No es
2127
+ * `getSessionId()`. Null hasta que el backend acepta el primer lote y de nuevo al cerrar la
2128
+ * sesión: para saber también qué registro se cerró, usa `init({ onFeedbackSession })`.
2129
+ */
2130
+ getFeedbackSessionId() {
2131
+ return this.analyticsFeedbackSessionId ?? null;
2132
+ }
2133
+ /** Avisa al host del registro abierto o cerrado; un fallo del host no corta el envío. */
2134
+ notifyFeedbackSession(sessionId, status) {
2135
+ try {
2136
+ this.onFeedbackSession?.({ sessionId, status });
2137
+ } catch (error) {
2138
+ this.log("analytics \xB7 onFeedbackSession threw:", error);
2139
+ }
2140
+ }
2094
2141
  /** Activa/desactiva el tracking (identidad + sesión + analytics). Kill-switch del contrato §7bis. */
2095
2142
  setTrackingEnabled(enabled) {
2096
2143
  if (!enabled) this.closeSession("tracking_disabled");
@@ -2931,7 +2978,7 @@ var DeepdotsPopups = class {
2931
2978
  }
2932
2979
  if (!this.popupContainer) return;
2933
2980
  const container = this.popupContainer;
2934
- void import("./renderPopup-E2OLIXIQ.mjs").then(({ renderPopup }) => {
2981
+ void import("./renderPopup-WLOFOCDR.mjs").then(({ renderPopup }) => {
2935
2982
  renderPopup(
2936
2983
  container,
2937
2984
  surveyId,