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