@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/react-native.d.mts
CHANGED
|
@@ -576,6 +576,13 @@ declare class DeepdotsPopups {
|
|
|
576
576
|
private safeParseUrl;
|
|
577
577
|
private mapPopupTriggerType;
|
|
578
578
|
private markSurveyProgress;
|
|
579
|
+
/**
|
|
580
|
+
* Rehidrata el estado de redisplay desde el storage. `answeredSurveys` se reconstruye
|
|
581
|
+
* desde las entradas COMPLETED: es exactamente lo que persiste `markSurveyAnswered`.
|
|
582
|
+
*/
|
|
583
|
+
private loadPopupState;
|
|
584
|
+
/** Vuelca el estado de redisplay al storage. Sin storage (o bloqueado) degrada a memoria. */
|
|
585
|
+
private persistPopupState;
|
|
579
586
|
private isPopupDefinition;
|
|
580
587
|
private isPopupTrigger;
|
|
581
588
|
private isPopupTriggerType;
|
package/dist/react-native.d.ts
CHANGED
|
@@ -576,6 +576,13 @@ declare class DeepdotsPopups {
|
|
|
576
576
|
private safeParseUrl;
|
|
577
577
|
private mapPopupTriggerType;
|
|
578
578
|
private markSurveyProgress;
|
|
579
|
+
/**
|
|
580
|
+
* Rehidrata el estado de redisplay desde el storage. `answeredSurveys` se reconstruye
|
|
581
|
+
* desde las entradas COMPLETED: es exactamente lo que persiste `markSurveyAnswered`.
|
|
582
|
+
*/
|
|
583
|
+
private loadPopupState;
|
|
584
|
+
/** Vuelca el estado de redisplay al storage. Sin storage (o bloqueado) degrada a memoria. */
|
|
585
|
+
private persistPopupState;
|
|
579
586
|
private isPopupDefinition;
|
|
580
587
|
private isPopupTrigger;
|
|
581
588
|
private isPopupTriggerType;
|
package/dist/react-native.js
CHANGED
|
@@ -4580,6 +4580,75 @@ var CrashReporter = class {
|
|
|
4580
4580
|
}
|
|
4581
4581
|
};
|
|
4582
4582
|
|
|
4583
|
+
// src/core/popup-state-store.ts
|
|
4584
|
+
var POPUP_STATE_STORAGE_KEY = "deepdots.popups.state";
|
|
4585
|
+
var MAX_TRACKED_POPUP_ENTRIES = 200;
|
|
4586
|
+
function emptyState() {
|
|
4587
|
+
return { lastShown: {}, progress: {} };
|
|
4588
|
+
}
|
|
4589
|
+
function isValidTimestamp(value) {
|
|
4590
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
4591
|
+
}
|
|
4592
|
+
function capEntries(entries, timestampOf) {
|
|
4593
|
+
if (entries.length <= MAX_TRACKED_POPUP_ENTRIES) return entries;
|
|
4594
|
+
return [...entries].sort((a, b) => timestampOf(b[1]) - timestampOf(a[1])).slice(0, MAX_TRACKED_POPUP_ENTRIES);
|
|
4595
|
+
}
|
|
4596
|
+
function readPopupState(storage) {
|
|
4597
|
+
let raw = null;
|
|
4598
|
+
try {
|
|
4599
|
+
raw = storage.getItem(POPUP_STATE_STORAGE_KEY);
|
|
4600
|
+
} catch {
|
|
4601
|
+
return emptyState();
|
|
4602
|
+
}
|
|
4603
|
+
if (!raw) return emptyState();
|
|
4604
|
+
let parsed;
|
|
4605
|
+
try {
|
|
4606
|
+
parsed = JSON.parse(raw);
|
|
4607
|
+
} catch {
|
|
4608
|
+
return emptyState();
|
|
4609
|
+
}
|
|
4610
|
+
if (typeof parsed !== "object" || parsed === null) return emptyState();
|
|
4611
|
+
const source = parsed;
|
|
4612
|
+
const state = emptyState();
|
|
4613
|
+
if (typeof source.lastShown === "object" && source.lastShown !== null) {
|
|
4614
|
+
const valid = Object.entries(source.lastShown).filter((entry) => isValidTimestamp(entry[1]));
|
|
4615
|
+
capEntries(valid, (timestamp) => timestamp).forEach(([popupId, timestamp]) => {
|
|
4616
|
+
state.lastShown[popupId] = timestamp;
|
|
4617
|
+
});
|
|
4618
|
+
}
|
|
4619
|
+
if (typeof source.progress === "object" && source.progress !== null) {
|
|
4620
|
+
const valid = Object.entries(source.progress).filter((entry) => {
|
|
4621
|
+
const value = entry[1];
|
|
4622
|
+
if (typeof value !== "object" || value === null) return false;
|
|
4623
|
+
const candidate = value;
|
|
4624
|
+
return POPUP_TRIGGER_CONDITION_STATUSES.includes(candidate.status) && isValidTimestamp(candidate.timestamp);
|
|
4625
|
+
});
|
|
4626
|
+
capEntries(valid, (entry) => entry.timestamp).forEach(([surveyId, entry]) => {
|
|
4627
|
+
state.progress[surveyId] = { status: entry.status, timestamp: entry.timestamp };
|
|
4628
|
+
});
|
|
4629
|
+
}
|
|
4630
|
+
return state;
|
|
4631
|
+
}
|
|
4632
|
+
function writePopupState(storage, state) {
|
|
4633
|
+
const capped = emptyState();
|
|
4634
|
+
capEntries(Object.entries(state.lastShown), (timestamp) => timestamp).forEach(([popupId, timestamp]) => {
|
|
4635
|
+
capped.lastShown[popupId] = timestamp;
|
|
4636
|
+
});
|
|
4637
|
+
capEntries(Object.entries(state.progress), (entry) => entry.timestamp).forEach(([surveyId, entry]) => {
|
|
4638
|
+
capped.progress[surveyId] = entry;
|
|
4639
|
+
});
|
|
4640
|
+
try {
|
|
4641
|
+
storage.setItem(POPUP_STATE_STORAGE_KEY, JSON.stringify(capped));
|
|
4642
|
+
} catch {
|
|
4643
|
+
}
|
|
4644
|
+
}
|
|
4645
|
+
function clearPopupState(storage) {
|
|
4646
|
+
try {
|
|
4647
|
+
storage.removeItem(POPUP_STATE_STORAGE_KEY);
|
|
4648
|
+
} catch {
|
|
4649
|
+
}
|
|
4650
|
+
}
|
|
4651
|
+
|
|
4583
4652
|
// src/core/deepdots-popups.ts
|
|
4584
4653
|
init_logger();
|
|
4585
4654
|
|
|
@@ -4670,6 +4739,10 @@ var DeepdotsPopups = class {
|
|
|
4670
4739
|
this.popupDefinitions = [];
|
|
4671
4740
|
this.popupsLoaded = false;
|
|
4672
4741
|
this.pendingAutoLaunch = false;
|
|
4742
|
+
// Estado que alimenta las reglas de redisplay. Copia de trabajo en memoria; la fuente
|
|
4743
|
+
// duradera es el storage (`popup-state-store`), rehidratada en `init()` — sin eso, una
|
|
4744
|
+
// recarga reiniciaba el cooldown y el popup volvía a salir. `answeredSurveys` se deriva
|
|
4745
|
+
// de las entradas COMPLETED de `surveyProgress` (los dos los escribe `markSurveyAnswered`).
|
|
4673
4746
|
this.answeredSurveys = /* @__PURE__ */ new Set();
|
|
4674
4747
|
this.surveyProgress = /* @__PURE__ */ new Map();
|
|
4675
4748
|
this.lastShown = /* @__PURE__ */ new Map();
|
|
@@ -4745,6 +4818,7 @@ var DeepdotsPopups = class {
|
|
|
4745
4818
|
};
|
|
4746
4819
|
const storage = config.storage ?? createDefaultStorage();
|
|
4747
4820
|
this.storage = storage;
|
|
4821
|
+
this.loadPopupState(storage);
|
|
4748
4822
|
this.tracking = new TrackingManager({
|
|
4749
4823
|
storage,
|
|
4750
4824
|
clientUserId: this.config.userId,
|
|
@@ -5012,6 +5086,10 @@ var DeepdotsPopups = class {
|
|
|
5012
5086
|
}) : null;
|
|
5013
5087
|
this.analytics?.resetUserScope();
|
|
5014
5088
|
this.messageGuard.reset();
|
|
5089
|
+
this.lastShown.clear();
|
|
5090
|
+
this.surveyProgress.clear();
|
|
5091
|
+
this.answeredSurveys.clear();
|
|
5092
|
+
clearPopupState(storage);
|
|
5015
5093
|
this.log("tracking \xB7 user_change \xB7 user_id:", this.tracking.getUserId());
|
|
5016
5094
|
this.openSession();
|
|
5017
5095
|
}
|
|
@@ -5183,6 +5261,7 @@ var DeepdotsPopups = class {
|
|
|
5183
5261
|
this.log("Showing popup (definition)", def);
|
|
5184
5262
|
this.surveyToPopupId.set(def.surveyId, def.id);
|
|
5185
5263
|
this.lastShown.set(def.id, Date.now());
|
|
5264
|
+
this.persistPopupState();
|
|
5186
5265
|
this.renderPopup(def.surveyId, def.productId, def.actions, def.style, def.title);
|
|
5187
5266
|
this.emitEvent("popup_shown", def.surveyId, { popupId: def.id });
|
|
5188
5267
|
}
|
|
@@ -5662,6 +5741,29 @@ var DeepdotsPopups = class {
|
|
|
5662
5741
|
return;
|
|
5663
5742
|
}
|
|
5664
5743
|
this.surveyProgress.set(surveyId, { status, timestamp: Date.now() });
|
|
5744
|
+
this.persistPopupState();
|
|
5745
|
+
}
|
|
5746
|
+
/**
|
|
5747
|
+
* Rehidrata el estado de redisplay desde el storage. `answeredSurveys` se reconstruye
|
|
5748
|
+
* desde las entradas COMPLETED: es exactamente lo que persiste `markSurveyAnswered`.
|
|
5749
|
+
*/
|
|
5750
|
+
loadPopupState(storage) {
|
|
5751
|
+
const state = readPopupState(storage);
|
|
5752
|
+
Object.entries(state.lastShown).forEach(([popupId, timestamp]) => {
|
|
5753
|
+
this.lastShown.set(popupId, timestamp);
|
|
5754
|
+
});
|
|
5755
|
+
Object.entries(state.progress).forEach(([surveyId, entry]) => {
|
|
5756
|
+
this.surveyProgress.set(surveyId, { status: entry.status, timestamp: entry.timestamp });
|
|
5757
|
+
if (entry.status === "COMPLETED") this.answeredSurveys.add(surveyId);
|
|
5758
|
+
});
|
|
5759
|
+
}
|
|
5760
|
+
/** Vuelca el estado de redisplay al storage. Sin storage (o bloqueado) degrada a memoria. */
|
|
5761
|
+
persistPopupState() {
|
|
5762
|
+
if (!this.storage) return;
|
|
5763
|
+
writePopupState(this.storage, {
|
|
5764
|
+
lastShown: Object.fromEntries(this.lastShown),
|
|
5765
|
+
progress: Object.fromEntries(this.surveyProgress)
|
|
5766
|
+
});
|
|
5665
5767
|
}
|
|
5666
5768
|
isPopupDefinition(value) {
|
|
5667
5769
|
if (typeof value !== "object" || value === null) return false;
|