@magicfeedback/popup-sdk 1.7.0 → 1.7.1
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 +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +104 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +104 -2
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +7 -0
- package/dist/react-native.d.ts +7 -0
- package/dist/react-native.js +102 -0
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +102 -0
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-IHGYFMXO.mjs → renderPopup-HHQMAW3G.mjs} +3 -3
- package/dist/renderPopup-HHQMAW3G.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/renderPopup-IHGYFMXO.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -811,7 +811,7 @@ var BrowserPopupRenderer = class {
|
|
|
811
811
|
if (!this.container) return;
|
|
812
812
|
this.visible = true;
|
|
813
813
|
const container = this.container;
|
|
814
|
-
void import("./renderPopup-
|
|
814
|
+
void import("./renderPopup-HHQMAW3G.mjs").then(({ renderPopup }) => {
|
|
815
815
|
renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId, options);
|
|
816
816
|
});
|
|
817
817
|
}
|
|
@@ -1563,6 +1563,75 @@ var CrashReporter = class {
|
|
|
1563
1563
|
}
|
|
1564
1564
|
};
|
|
1565
1565
|
|
|
1566
|
+
// src/core/popup-state-store.ts
|
|
1567
|
+
var POPUP_STATE_STORAGE_KEY = "deepdots.popups.state";
|
|
1568
|
+
var MAX_TRACKED_POPUP_ENTRIES = 200;
|
|
1569
|
+
function emptyState() {
|
|
1570
|
+
return { lastShown: {}, progress: {} };
|
|
1571
|
+
}
|
|
1572
|
+
function isValidTimestamp(value) {
|
|
1573
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
1574
|
+
}
|
|
1575
|
+
function capEntries(entries, timestampOf) {
|
|
1576
|
+
if (entries.length <= MAX_TRACKED_POPUP_ENTRIES) return entries;
|
|
1577
|
+
return [...entries].sort((a, b) => timestampOf(b[1]) - timestampOf(a[1])).slice(0, MAX_TRACKED_POPUP_ENTRIES);
|
|
1578
|
+
}
|
|
1579
|
+
function readPopupState(storage) {
|
|
1580
|
+
let raw = null;
|
|
1581
|
+
try {
|
|
1582
|
+
raw = storage.getItem(POPUP_STATE_STORAGE_KEY);
|
|
1583
|
+
} catch {
|
|
1584
|
+
return emptyState();
|
|
1585
|
+
}
|
|
1586
|
+
if (!raw) return emptyState();
|
|
1587
|
+
let parsed;
|
|
1588
|
+
try {
|
|
1589
|
+
parsed = JSON.parse(raw);
|
|
1590
|
+
} catch {
|
|
1591
|
+
return emptyState();
|
|
1592
|
+
}
|
|
1593
|
+
if (typeof parsed !== "object" || parsed === null) return emptyState();
|
|
1594
|
+
const source = parsed;
|
|
1595
|
+
const state = emptyState();
|
|
1596
|
+
if (typeof source.lastShown === "object" && source.lastShown !== null) {
|
|
1597
|
+
const valid = Object.entries(source.lastShown).filter((entry) => isValidTimestamp(entry[1]));
|
|
1598
|
+
capEntries(valid, (timestamp) => timestamp).forEach(([popupId, timestamp]) => {
|
|
1599
|
+
state.lastShown[popupId] = timestamp;
|
|
1600
|
+
});
|
|
1601
|
+
}
|
|
1602
|
+
if (typeof source.progress === "object" && source.progress !== null) {
|
|
1603
|
+
const valid = Object.entries(source.progress).filter((entry) => {
|
|
1604
|
+
const value = entry[1];
|
|
1605
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1606
|
+
const candidate = value;
|
|
1607
|
+
return POPUP_TRIGGER_CONDITION_STATUSES.includes(candidate.status) && isValidTimestamp(candidate.timestamp);
|
|
1608
|
+
});
|
|
1609
|
+
capEntries(valid, (entry) => entry.timestamp).forEach(([surveyId, entry]) => {
|
|
1610
|
+
state.progress[surveyId] = { status: entry.status, timestamp: entry.timestamp };
|
|
1611
|
+
});
|
|
1612
|
+
}
|
|
1613
|
+
return state;
|
|
1614
|
+
}
|
|
1615
|
+
function writePopupState(storage, state) {
|
|
1616
|
+
const capped = emptyState();
|
|
1617
|
+
capEntries(Object.entries(state.lastShown), (timestamp) => timestamp).forEach(([popupId, timestamp]) => {
|
|
1618
|
+
capped.lastShown[popupId] = timestamp;
|
|
1619
|
+
});
|
|
1620
|
+
capEntries(Object.entries(state.progress), (entry) => entry.timestamp).forEach(([surveyId, entry]) => {
|
|
1621
|
+
capped.progress[surveyId] = entry;
|
|
1622
|
+
});
|
|
1623
|
+
try {
|
|
1624
|
+
storage.setItem(POPUP_STATE_STORAGE_KEY, JSON.stringify(capped));
|
|
1625
|
+
} catch {
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
function clearPopupState(storage) {
|
|
1629
|
+
try {
|
|
1630
|
+
storage.removeItem(POPUP_STATE_STORAGE_KEY);
|
|
1631
|
+
} catch {
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1566
1635
|
// src/analytics/messaging.ts
|
|
1567
1636
|
var MESSAGE_CHANNELS = ["push", "in_app"];
|
|
1568
1637
|
function buildMessageParams(stage, o) {
|
|
@@ -1650,6 +1719,10 @@ var DeepdotsPopups = class {
|
|
|
1650
1719
|
this.popupDefinitions = [];
|
|
1651
1720
|
this.popupsLoaded = false;
|
|
1652
1721
|
this.pendingAutoLaunch = false;
|
|
1722
|
+
// Estado que alimenta las reglas de redisplay. Copia de trabajo en memoria; la fuente
|
|
1723
|
+
// duradera es el storage (`popup-state-store`), rehidratada en `init()` — sin eso, una
|
|
1724
|
+
// recarga reiniciaba el cooldown y el popup volvía a salir. `answeredSurveys` se deriva
|
|
1725
|
+
// de las entradas COMPLETED de `surveyProgress` (los dos los escribe `markSurveyAnswered`).
|
|
1653
1726
|
this.answeredSurveys = /* @__PURE__ */ new Set();
|
|
1654
1727
|
this.surveyProgress = /* @__PURE__ */ new Map();
|
|
1655
1728
|
this.lastShown = /* @__PURE__ */ new Map();
|
|
@@ -1725,6 +1798,7 @@ var DeepdotsPopups = class {
|
|
|
1725
1798
|
};
|
|
1726
1799
|
const storage = config.storage ?? createDefaultStorage();
|
|
1727
1800
|
this.storage = storage;
|
|
1801
|
+
this.loadPopupState(storage);
|
|
1728
1802
|
this.tracking = new TrackingManager({
|
|
1729
1803
|
storage,
|
|
1730
1804
|
clientUserId: this.config.userId,
|
|
@@ -1992,6 +2066,10 @@ var DeepdotsPopups = class {
|
|
|
1992
2066
|
}) : null;
|
|
1993
2067
|
this.analytics?.resetUserScope();
|
|
1994
2068
|
this.messageGuard.reset();
|
|
2069
|
+
this.lastShown.clear();
|
|
2070
|
+
this.surveyProgress.clear();
|
|
2071
|
+
this.answeredSurveys.clear();
|
|
2072
|
+
clearPopupState(storage);
|
|
1995
2073
|
this.log("tracking \xB7 user_change \xB7 user_id:", this.tracking.getUserId());
|
|
1996
2074
|
this.openSession();
|
|
1997
2075
|
}
|
|
@@ -2163,6 +2241,7 @@ var DeepdotsPopups = class {
|
|
|
2163
2241
|
this.log("Showing popup (definition)", def);
|
|
2164
2242
|
this.surveyToPopupId.set(def.surveyId, def.id);
|
|
2165
2243
|
this.lastShown.set(def.id, Date.now());
|
|
2244
|
+
this.persistPopupState();
|
|
2166
2245
|
this.renderPopup(def.surveyId, def.productId, def.actions, def.style, def.title);
|
|
2167
2246
|
this.emitEvent("popup_shown", def.surveyId, { popupId: def.id });
|
|
2168
2247
|
}
|
|
@@ -2527,7 +2606,7 @@ var DeepdotsPopups = class {
|
|
|
2527
2606
|
}
|
|
2528
2607
|
if (!this.popupContainer) return;
|
|
2529
2608
|
const container = this.popupContainer;
|
|
2530
|
-
void import("./renderPopup-
|
|
2609
|
+
void import("./renderPopup-HHQMAW3G.mjs").then(({ renderPopup }) => {
|
|
2531
2610
|
renderPopup(
|
|
2532
2611
|
container,
|
|
2533
2612
|
surveyId,
|
|
@@ -2642,6 +2721,29 @@ var DeepdotsPopups = class {
|
|
|
2642
2721
|
return;
|
|
2643
2722
|
}
|
|
2644
2723
|
this.surveyProgress.set(surveyId, { status, timestamp: Date.now() });
|
|
2724
|
+
this.persistPopupState();
|
|
2725
|
+
}
|
|
2726
|
+
/**
|
|
2727
|
+
* Rehidrata el estado de redisplay desde el storage. `answeredSurveys` se reconstruye
|
|
2728
|
+
* desde las entradas COMPLETED: es exactamente lo que persiste `markSurveyAnswered`.
|
|
2729
|
+
*/
|
|
2730
|
+
loadPopupState(storage) {
|
|
2731
|
+
const state = readPopupState(storage);
|
|
2732
|
+
Object.entries(state.lastShown).forEach(([popupId, timestamp]) => {
|
|
2733
|
+
this.lastShown.set(popupId, timestamp);
|
|
2734
|
+
});
|
|
2735
|
+
Object.entries(state.progress).forEach(([surveyId, entry]) => {
|
|
2736
|
+
this.surveyProgress.set(surveyId, { status: entry.status, timestamp: entry.timestamp });
|
|
2737
|
+
if (entry.status === "COMPLETED") this.answeredSurveys.add(surveyId);
|
|
2738
|
+
});
|
|
2739
|
+
}
|
|
2740
|
+
/** Vuelca el estado de redisplay al storage. Sin storage (o bloqueado) degrada a memoria. */
|
|
2741
|
+
persistPopupState() {
|
|
2742
|
+
if (!this.storage) return;
|
|
2743
|
+
writePopupState(this.storage, {
|
|
2744
|
+
lastShown: Object.fromEntries(this.lastShown),
|
|
2745
|
+
progress: Object.fromEntries(this.surveyProgress)
|
|
2746
|
+
});
|
|
2645
2747
|
}
|
|
2646
2748
|
isPopupDefinition(value) {
|
|
2647
2749
|
if (typeof value !== "object" || value === null) return false;
|