@virex-tech/paywallo-sdk 2.6.0 → 2.6.2

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.js CHANGED
@@ -491,7 +491,7 @@ async function readAnonIdDurably(storage) {
491
491
  if (secure) return secure;
492
492
  return nativeStorage.get(ANON_ID_FALLBACK_KEY);
493
493
  }
494
- var DEVICE_ID_KEY, ANON_ID_FALLBACK_KEY, ANON_ID_KEY, USER_EMAIL_KEY, USER_PROPERTIES_KEY, USER_DISTINCT_ID_KEY, USER_NAME_KEY, USER_COUNTRY_KEY, USER_LOCALE_KEY, USER_PHONE_KEY, USER_FIRST_NAME_KEY, USER_LAST_NAME_KEY, USER_DOB_KEY, USER_GENDER_KEY, LEGACY_USER_PHONE_KEY, LEGACY_USER_FIRST_NAME_KEY, LEGACY_USER_LAST_NAME_KEY, LEGACY_USER_DOB_KEY, LEGACY_USER_GENDER_KEY, LEGACY_DEVICE_ID_KEY, LEGACY_ANON_ID_KEY, LEGACY_EMAIL_KEY, LEGACY_PROPERTIES_KEY, LEGACY_DISTINCT_ID_KEY, LEGACY_NAME_KEY, LEGACY_COUNTRY_KEY, LEGACY_LOCALE_KEY, ANON_ID_SET_RETRIES, ANON_ID_RETRY_DELAY_MS;
494
+ var DEVICE_ID_KEY, ANON_ID_FALLBACK_KEY, ANON_ID_KEY, USER_EMAIL_KEY, USER_PROPERTIES_KEY, USER_DISTINCT_ID_KEY, USER_NAME_KEY, USER_COUNTRY_KEY, USER_LOCALE_KEY, USER_PHONE_KEY, USER_FIRST_NAME_KEY, USER_LAST_NAME_KEY, USER_DOB_KEY, USER_GENDER_KEY, USER_ZIP_KEY, LEGACY_USER_PHONE_KEY, LEGACY_USER_FIRST_NAME_KEY, LEGACY_USER_LAST_NAME_KEY, LEGACY_USER_DOB_KEY, LEGACY_USER_GENDER_KEY, LEGACY_DEVICE_ID_KEY, LEGACY_ANON_ID_KEY, LEGACY_EMAIL_KEY, LEGACY_PROPERTIES_KEY, LEGACY_DISTINCT_ID_KEY, LEGACY_NAME_KEY, LEGACY_COUNTRY_KEY, LEGACY_LOCALE_KEY, ANON_ID_SET_RETRIES, ANON_ID_RETRY_DELAY_MS;
495
495
  var init_IdentityStorage = __esm({
496
496
  "src/domains/identity/IdentityStorage.ts"() {
497
497
  "use strict";
@@ -510,6 +510,7 @@ var init_IdentityStorage = __esm({
510
510
  USER_LAST_NAME_KEY = "@paywallo:user_last_name";
511
511
  USER_DOB_KEY = "@paywallo:user_dob";
512
512
  USER_GENDER_KEY = "@paywallo:user_gender";
513
+ USER_ZIP_KEY = "@paywallo:user_zip";
513
514
  LEGACY_USER_PHONE_KEY = "@panel:user_phone";
514
515
  LEGACY_USER_FIRST_NAME_KEY = "@panel:user_first_name";
515
516
  LEGACY_USER_LAST_NAME_KEY = "@panel:user_last_name";
@@ -560,6 +561,7 @@ var init_IdentityManager = __esm({
560
561
  this.lastName = null;
561
562
  this.dateOfBirth = null;
562
563
  this.gender = null;
564
+ this.zipCode = null;
563
565
  this.apiClient = null;
564
566
  this.secureStorage = null;
565
567
  this.debug = false;
@@ -614,7 +616,7 @@ var init_IdentityManager = __esm({
614
616
  let email;
615
617
  let properties;
616
618
  if (options) {
617
- if ("email" in options || "properties" in options || "phone" in options || "firstName" in options || "lastName" in options || "dateOfBirth" in options || "gender" in options) {
619
+ if ("email" in options || "properties" in options || "phone" in options || "firstName" in options || "lastName" in options || "dateOfBirth" in options || "gender" in options || "zipCode" in options) {
618
620
  email = options.email;
619
621
  properties = options.properties;
620
622
  } else {
@@ -655,6 +657,10 @@ var init_IdentityManager = __esm({
655
657
  this.gender = opts.gender;
656
658
  await this.secureStorage.set(USER_GENDER_KEY, this.gender);
657
659
  }
660
+ if (opts?.zipCode) {
661
+ this.zipCode = opts.zipCode;
662
+ await this.secureStorage.set(USER_ZIP_KEY, this.zipCode);
663
+ }
658
664
  if (this.apiClient && this.anonId) {
659
665
  try {
660
666
  await this.apiClient.identify(this.anonId, properties, email, this.deviceId ?? void 0, {
@@ -662,7 +668,8 @@ var init_IdentityManager = __esm({
662
668
  firstName: this.firstName ?? void 0,
663
669
  lastName: this.lastName ?? void 0,
664
670
  dateOfBirth: this.dateOfBirth ?? void 0,
665
- gender: this.gender ?? void 0
671
+ gender: this.gender ?? void 0,
672
+ zipCode: this.zipCode ?? void 0
666
673
  });
667
674
  if (this.debug) console.log("[Paywallo] identify confirmed", this.anonId.slice(0, 8));
668
675
  } catch (err) {
@@ -712,6 +719,7 @@ var init_IdentityManager = __esm({
712
719
  this.lastName = null;
713
720
  this.dateOfBirth = null;
714
721
  this.gender = null;
722
+ this.zipCode = null;
715
723
  await Promise.all([
716
724
  this.secureStorage?.set(ANON_ID_KEY, newAnonId) ?? Promise.resolve(false),
717
725
  this.secureStorage?.remove(USER_EMAIL_KEY) ?? Promise.resolve(false),
@@ -720,7 +728,8 @@ var init_IdentityManager = __esm({
720
728
  this.secureStorage?.remove(USER_FIRST_NAME_KEY) ?? Promise.resolve(false),
721
729
  this.secureStorage?.remove(USER_LAST_NAME_KEY) ?? Promise.resolve(false),
722
730
  this.secureStorage?.remove(USER_DOB_KEY) ?? Promise.resolve(false),
723
- this.secureStorage?.remove(USER_GENDER_KEY) ?? Promise.resolve(false)
731
+ this.secureStorage?.remove(USER_GENDER_KEY) ?? Promise.resolve(false),
732
+ this.secureStorage?.remove(USER_ZIP_KEY) ?? Promise.resolve(false)
724
733
  ]);
725
734
  }
726
735
  getState() {
@@ -732,7 +741,8 @@ var init_IdentityManager = __esm({
732
741
  firstName: this.firstName,
733
742
  lastName: this.lastName,
734
743
  dateOfBirth: this.dateOfBirth,
735
- gender: this.gender
744
+ gender: this.gender,
745
+ zipCode: this.zipCode
736
746
  };
737
747
  }
738
748
  isSecureStorageAvailable() {
@@ -950,17 +960,39 @@ var init_campaign = __esm({
950
960
  }
951
961
  });
952
962
 
963
+ // src/domains/identity/NativeAdvertisingId.ts
964
+ var import_react_native3, nativeModule, nativeAdvertisingId;
965
+ var init_NativeAdvertisingId = __esm({
966
+ "src/domains/identity/NativeAdvertisingId.ts"() {
967
+ "use strict";
968
+ import_react_native3 = require("react-native");
969
+ nativeModule = import_react_native3.NativeModules.PaywalloAdvertisingId ?? null;
970
+ nativeAdvertisingId = {
971
+ async getAdvertisingId() {
972
+ try {
973
+ return await nativeModule?.getAdvertisingId?.() ?? null;
974
+ } catch {
975
+ return null;
976
+ }
977
+ }
978
+ };
979
+ }
980
+ });
981
+
953
982
  // src/domains/identity/AdvertisingIdManager.ts
954
- var import_react_native3, ZERO_IDFA, AdvertisingIdManager, advertisingIdManager;
983
+ var import_react_native4, ZERO_IDFA, ATT_PROMPT_TIMEOUT_MS, AdvertisingIdManager, advertisingIdManager;
955
984
  var init_AdvertisingIdManager = __esm({
956
985
  "src/domains/identity/AdvertisingIdManager.ts"() {
957
986
  "use strict";
958
- import_react_native3 = require("react-native");
987
+ import_react_native4 = require("react-native");
959
988
  init_NativeDeviceInfo();
989
+ init_NativeAdvertisingId();
960
990
  ZERO_IDFA = "00000000-0000-0000-0000-000000000000";
991
+ ATT_PROMPT_TIMEOUT_MS = 4e3;
961
992
  AdvertisingIdManager = class {
962
- constructor() {
993
+ constructor(debug = false) {
963
994
  this.cached = null;
995
+ this.debug = debug;
964
996
  }
965
997
  /**
966
998
  * Synchronous accessor for the cached collect() result. Returns null until
@@ -975,9 +1007,12 @@ var init_AdvertisingIdManager = __esm({
975
1007
  return this.cached;
976
1008
  }
977
1009
  const fallback = { idfv: null, idfa: null, gaid: null, attStatus: "unavailable" };
1010
+ if (import_react_native4.Platform.OS === "android") {
1011
+ return this.collectAndroid();
1012
+ }
978
1013
  try {
979
1014
  const tracking = await import("expo-tracking-transparency");
980
- if (import_react_native3.Platform.OS === "ios") {
1015
+ if (import_react_native4.Platform.OS === "ios") {
981
1016
  if (!tracking.isAvailable()) {
982
1017
  const idfv2 = await this.collectIdfv();
983
1018
  const result2 = { ...fallback, idfv: idfv2 };
@@ -988,9 +1023,20 @@ var init_AdvertisingIdManager = __esm({
988
1023
  let status = current.status;
989
1024
  let granted = current.granted;
990
1025
  if (status === "undetermined" && requestATT) {
991
- const result2 = await tracking.requestTrackingPermissionsAsync();
992
- status = result2.status;
993
- granted = result2.granted;
1026
+ const result2 = await Promise.race([
1027
+ tracking.requestTrackingPermissionsAsync(),
1028
+ new Promise((r) => setTimeout(() => r(null), ATT_PROMPT_TIMEOUT_MS))
1029
+ ]);
1030
+ if (result2 === null) {
1031
+ if (this.debug) {
1032
+ console.log(`[Paywallo] ATT prompt timed out after ${ATT_PROMPT_TIMEOUT_MS}ms \u2014 treating as undetermined`);
1033
+ }
1034
+ status = "undetermined";
1035
+ granted = false;
1036
+ } else {
1037
+ status = result2.status;
1038
+ granted = result2.granted;
1039
+ }
994
1040
  }
995
1041
  const idfv = await this.collectIdfv();
996
1042
  const idfa = granted ? this.sanitizeId(tracking.getAdvertisingId()) : null;
@@ -998,12 +1044,6 @@ var init_AdvertisingIdManager = __esm({
998
1044
  if (idfv !== null) this.cached = result;
999
1045
  return result;
1000
1046
  }
1001
- if (import_react_native3.Platform.OS === "android") {
1002
- const rawGaid = tracking.getAdvertisingId();
1003
- const gaid = this.sanitizeId(rawGaid);
1004
- this.cached = { idfv: null, idfa: null, gaid, attStatus: "unavailable" };
1005
- return this.cached;
1006
- }
1007
1047
  this.cached = fallback;
1008
1048
  return this.cached;
1009
1049
  } catch {
@@ -1011,6 +1051,27 @@ var init_AdvertisingIdManager = __esm({
1011
1051
  return this.cached;
1012
1052
  }
1013
1053
  }
1054
+ async collectAndroid() {
1055
+ const nativeGaid = this.sanitizeId(
1056
+ await Promise.race([
1057
+ nativeAdvertisingId.getAdvertisingId(),
1058
+ new Promise((r) => setTimeout(() => r(null), 1500))
1059
+ ])
1060
+ );
1061
+ if (nativeGaid !== null) {
1062
+ this.cached = { idfv: null, idfa: null, gaid: nativeGaid, attStatus: "unavailable" };
1063
+ return this.cached;
1064
+ }
1065
+ try {
1066
+ const tracking = await import("expo-tracking-transparency");
1067
+ const gaid = this.sanitizeId(tracking.getAdvertisingId());
1068
+ this.cached = { idfv: null, idfa: null, gaid, attStatus: "unavailable" };
1069
+ return this.cached;
1070
+ } catch {
1071
+ this.cached = { idfv: null, idfa: null, gaid: null, attStatus: "unavailable" };
1072
+ return this.cached;
1073
+ }
1074
+ }
1014
1075
  async collectIdfv() {
1015
1076
  const RETRY_DELAY_MS = 80;
1016
1077
  const MAX_ATTEMPTS = 3;
@@ -1154,11 +1215,11 @@ var init_sessionTracking = __esm({
1154
1215
  });
1155
1216
 
1156
1217
  // src/domains/session/SessionManager.ts
1157
- var import_react_native4, SESSION_ID_KEY, SESSION_START_KEY, LEGACY_SESSION_ID_KEY, LEGACY_SESSION_START_KEY, SESSION_TIMEOUT_MS, SessionManager, sessionManager;
1218
+ var import_react_native5, SESSION_ID_KEY, SESSION_START_KEY, LEGACY_SESSION_ID_KEY, LEGACY_SESSION_START_KEY, SESSION_TIMEOUT_MS, SessionManager, sessionManager;
1158
1219
  var init_SessionManager = __esm({
1159
1220
  "src/domains/session/SessionManager.ts"() {
1160
1221
  "use strict";
1161
- import_react_native4 = require("react-native");
1222
+ import_react_native5 = require("react-native");
1162
1223
  init_SecureStorage();
1163
1224
  init_uuid();
1164
1225
  init_distinctIdGuard();
@@ -1314,7 +1375,7 @@ var init_SessionManager = __esm({
1314
1375
  if (this.appStateSubscription) {
1315
1376
  this.appStateSubscription.remove();
1316
1377
  }
1317
- this.appStateSubscription = import_react_native4.AppState.addEventListener("change", this.handleAppStateChange);
1378
+ this.appStateSubscription = import_react_native5.AppState.addEventListener("change", this.handleAppStateChange);
1318
1379
  }
1319
1380
  async handleForeground() {
1320
1381
  const elapsed = this.backgroundTimestamp ? Date.now() - this.backgroundTimestamp : null;
@@ -1617,13 +1678,13 @@ var init_deferredAppLink = __esm({
1617
1678
  });
1618
1679
 
1619
1680
  // src/domains/identity/MetaBridge.ts
1620
- var import_react_native5, TIMEOUT_MS, NativeBridge, MetaBridge, metaBridge;
1681
+ var import_react_native6, TIMEOUT_MS, NativeBridge, MetaBridge, metaBridge;
1621
1682
  var init_MetaBridge = __esm({
1622
1683
  "src/domains/identity/MetaBridge.ts"() {
1623
1684
  "use strict";
1624
- import_react_native5 = require("react-native");
1685
+ import_react_native6 = require("react-native");
1625
1686
  TIMEOUT_MS = 2e3;
1626
- NativeBridge = import_react_native5.NativeModules.PaywalloFBBridge ?? null;
1687
+ NativeBridge = import_react_native6.NativeModules.PaywalloFBBridge ?? null;
1627
1688
  MetaBridge = class {
1628
1689
  constructor() {
1629
1690
  this.cachedAnonId = null;
@@ -1715,18 +1776,18 @@ var init_MetaBridge = __esm({
1715
1776
  });
1716
1777
 
1717
1778
  // src/domains/identity/InstallReferrerManager.ts
1718
- var import_react_native6, REFERRER_TIMEOUT_MS, InstallReferrerManager, installReferrerManager;
1779
+ var import_react_native7, REFERRER_TIMEOUT_MS, InstallReferrerManager, installReferrerManager;
1719
1780
  var init_InstallReferrerManager = __esm({
1720
1781
  "src/domains/identity/InstallReferrerManager.ts"() {
1721
1782
  "use strict";
1722
- import_react_native6 = require("react-native");
1783
+ import_react_native7 = require("react-native");
1723
1784
  init_NativeDeviceInfo();
1724
1785
  init_deferredAppLink();
1725
1786
  init_MetaBridge();
1726
1787
  REFERRER_TIMEOUT_MS = 5e3;
1727
1788
  InstallReferrerManager = class {
1728
1789
  async getReferrer() {
1729
- if (import_react_native6.Platform.OS !== "android") {
1790
+ if (import_react_native7.Platform.OS !== "android") {
1730
1791
  return this.fetchDeferredReferrer();
1731
1792
  }
1732
1793
  let timerId;
@@ -1832,11 +1893,11 @@ function extractDeferredAttribution(raw) {
1832
1893
  }
1833
1894
  return Object.keys(out).length > 0 ? out : null;
1834
1895
  }
1835
- var import_react_native7, InstallTracker, DEFERRED_ATTRIBUTION_FIELDS;
1896
+ var import_react_native8, InstallTracker, DEFERRED_ATTRIBUTION_FIELDS;
1836
1897
  var init_InstallTracker = __esm({
1837
1898
  "src/domains/identity/InstallTracker.ts"() {
1838
1899
  "use strict";
1839
- import_react_native7 = require("react-native");
1900
+ import_react_native8 = require("react-native");
1840
1901
  init_SecureStorage();
1841
1902
  init_NativeDeviceInfo();
1842
1903
  init_distinctIdGuard();
@@ -1892,10 +1953,10 @@ var init_InstallTracker = __esm({
1892
1953
  }
1893
1954
  let deviceData = {};
1894
1955
  try {
1895
- const screen = import_react_native7.Dimensions.get("screen");
1956
+ const screen = import_react_native8.Dimensions.get("screen");
1896
1957
  const screenWidth = Math.round(screen.width ?? 0);
1897
1958
  const screenHeight = Math.round(screen.height ?? 0);
1898
- const screenDensity = import_react_native7.PixelRatio.get();
1959
+ const screenDensity = import_react_native8.PixelRatio.get();
1899
1960
  const locale = Intl.DateTimeFormat().resolvedOptions().locale ?? "unknown";
1900
1961
  const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone ?? "unknown";
1901
1962
  const info = await nativeDeviceInfo.getDeviceInfo();
@@ -1956,13 +2017,14 @@ var init_InstallTracker = __esm({
1956
2017
  } else {
1957
2018
  const { generateUUID: generateUUID2 } = await Promise.resolve().then(() => (init_uuid(), uuid_exports));
1958
2019
  effectiveAnonId = `PW_${generateUUID2()}`;
2020
+ if (this.debug) console.log("[Paywallo] fb_anon_id: gerado PW_ local (Facebook Android SDK ausente no host? _fbp real indispon\xEDvel \u2014 Meta n\xE3o reconhece PW_)");
1959
2021
  await storage.set(INSTALL_KEYS.ANON_ID, effectiveAnonId).catch(() => {
1960
2022
  });
1961
2023
  }
1962
2024
  }
1963
2025
  await apiClient.trackEvent("$app_installed", distinctId, {
1964
2026
  installedAt,
1965
- platform: import_react_native7.Platform.OS,
2027
+ platform: import_react_native8.Platform.OS,
1966
2028
  installEventId,
1967
2029
  ...sessionId && { sessionId },
1968
2030
  ...deviceData,
@@ -1984,11 +2046,11 @@ var init_InstallTracker = __esm({
1984
2046
  ...adIds.gaid && { gaid: adIds.gaid },
1985
2047
  attStatus: adIds.attStatus
1986
2048
  }, void 0, { priority: "critical" });
1987
- void this.callDeferredMatch(apiClient, deviceData, adIds, effectiveAnonId, installedAt).catch(() => {
2049
+ void this.callDeferredMatch(apiClient, distinctId, deviceData, adIds, effectiveAnonId, installedAt).catch(() => {
1988
2050
  });
1989
2051
  await markInstallTracked(storage, installedAt);
1990
2052
  }
1991
- async callDeferredMatch(apiClient, deviceData, adIds, anonId, installedAt) {
2053
+ async callDeferredMatch(apiClient, distinctId, deviceData, adIds, anonId, installedAt) {
1992
2054
  const storage = new SecureStorage(this.debug);
1993
2055
  const alreadyMatched = await storage.get(INSTALL_KEYS.DEFERRED_MATCH_DONE);
1994
2056
  if (alreadyMatched) return;
@@ -2002,7 +2064,11 @@ var init_InstallTracker = __esm({
2002
2064
  method: "POST",
2003
2065
  headers: { "Content-Type": "application/json", "X-App-Key": appKey },
2004
2066
  body: JSON.stringify({
2005
- platform: import_react_native7.Platform.OS,
2067
+ platform: import_react_native8.Platform.OS,
2068
+ // Sem isto o servidor não tem identificador no Android (não há IDFV) e grava a
2069
+ // attribution com distinct_id vazio — o reader junta por
2070
+ // install_attributions.distinct_id = app_users.external_id e nunca casa.
2071
+ distinctId,
2006
2072
  ...adIds.idfv && { idfv: adIds.idfv },
2007
2073
  ...adIds.gaid && { gaid: adIds.gaid },
2008
2074
  ...referrer.rawReferrer && { installReferrer: referrer.rawReferrer },
@@ -2097,11 +2163,11 @@ function parseAttributionFromUrl(url) {
2097
2163
  return {};
2098
2164
  }
2099
2165
  }
2100
- var import_react_native8, DeepLinkAttributionCapture, deepLinkAttributionCapture;
2166
+ var import_react_native9, DeepLinkAttributionCapture, deepLinkAttributionCapture;
2101
2167
  var init_DeepLinkAttributionCapture = __esm({
2102
2168
  "src/domains/identity/DeepLinkAttributionCapture.ts"() {
2103
2169
  "use strict";
2104
- import_react_native8 = require("react-native");
2170
+ import_react_native9 = require("react-native");
2105
2171
  init_InstallTracker();
2106
2172
  DeepLinkAttributionCapture = class {
2107
2173
  constructor(debug = false) {
@@ -2110,7 +2176,7 @@ var init_DeepLinkAttributionCapture = __esm({
2110
2176
  }
2111
2177
  async start() {
2112
2178
  try {
2113
- const initialUrl = await import_react_native8.Linking.getInitialURL();
2179
+ const initialUrl = await import_react_native9.Linking.getInitialURL();
2114
2180
  const parsed = parseAttributionFromUrl(initialUrl);
2115
2181
  await attributionTracker.capture(parsed).catch(() => {
2116
2182
  });
@@ -2123,13 +2189,13 @@ var init_DeepLinkAttributionCapture = __esm({
2123
2189
  void attributionTracker.capture(parsed).catch(() => {
2124
2190
  });
2125
2191
  };
2126
- const maybeSub = import_react_native8.Linking.addEventListener("url", handler);
2192
+ const maybeSub = import_react_native9.Linking.addEventListener("url", handler);
2127
2193
  if (maybeSub && typeof maybeSub.remove === "function") {
2128
2194
  this.subscription = maybeSub;
2129
2195
  } else {
2130
2196
  this.subscription = {
2131
2197
  remove: () => {
2132
- const legacy = import_react_native8.Linking;
2198
+ const legacy = import_react_native9.Linking;
2133
2199
  legacy.removeEventListener?.("url", handler);
2134
2200
  }
2135
2201
  };
@@ -2164,10 +2230,10 @@ var init_identity = __esm({
2164
2230
 
2165
2231
  // src/domains/notifications/bridges/NativePushBridge.ts
2166
2232
  function getPaywalloNotifications() {
2167
- return import_react_native9.NativeModules.PaywalloNotifications ?? null;
2233
+ return import_react_native10.NativeModules.PaywalloNotifications ?? null;
2168
2234
  }
2169
2235
  function isNativePushAvailable() {
2170
- return !!import_react_native9.NativeModules.PaywalloNotifications;
2236
+ return !!import_react_native10.NativeModules.PaywalloNotifications;
2171
2237
  }
2172
2238
  function mapStatusToNumber(status) {
2173
2239
  switch (status) {
@@ -2189,16 +2255,16 @@ function mapStatusToNumber(status) {
2189
2255
  }
2190
2256
  function getEmitter() {
2191
2257
  if (_emitter) return _emitter;
2192
- const nativeMod = import_react_native9.NativeModules.PaywalloNotifications;
2258
+ const nativeMod = import_react_native10.NativeModules.PaywalloNotifications;
2193
2259
  if (!nativeMod) return null;
2194
- _emitter = new import_react_native9.NativeEventEmitter(nativeMod);
2260
+ _emitter = new import_react_native10.NativeEventEmitter(nativeMod);
2195
2261
  return _emitter;
2196
2262
  }
2197
- var import_react_native9, _emitter, NativePushBridge;
2263
+ var import_react_native10, _emitter, NativePushBridge;
2198
2264
  var init_NativePushBridge = __esm({
2199
2265
  "src/domains/notifications/bridges/NativePushBridge.ts"() {
2200
2266
  "use strict";
2201
- import_react_native9 = require("react-native");
2267
+ import_react_native10 = require("react-native");
2202
2268
  _emitter = null;
2203
2269
  NativePushBridge = class {
2204
2270
  async getToken() {
@@ -2211,7 +2277,7 @@ var init_NativePushBridge = __esm({
2211
2277
  }
2212
2278
  }
2213
2279
  async getAPNSToken() {
2214
- if (import_react_native9.Platform.OS !== "ios") return null;
2280
+ if (import_react_native10.Platform.OS !== "ios") return null;
2215
2281
  return this.getToken();
2216
2282
  }
2217
2283
  async requestPermission(options) {
@@ -2450,13 +2516,13 @@ function getTimezone() {
2450
2516
  }
2451
2517
  }
2452
2518
  function detectPlatform() {
2453
- return import_react_native10.Platform.OS === "ios" ? "ios" : "android";
2519
+ return import_react_native11.Platform.OS === "ios" ? "ios" : "android";
2454
2520
  }
2455
- var import_react_native10, SEEN_MESSAGES_KEY, LEGACY_SEEN_MESSAGES_KEY, SEEN_TTL_MS, MAX_SEEN_SIZE, NOTIFICATION_TYPE_TO_FAMILY, NotificationEventTracker;
2521
+ var import_react_native11, SEEN_MESSAGES_KEY, LEGACY_SEEN_MESSAGES_KEY, SEEN_TTL_MS, MAX_SEEN_SIZE, NOTIFICATION_TYPE_TO_FAMILY, NotificationEventTracker;
2456
2522
  var init_NotificationEventTracker = __esm({
2457
2523
  "src/domains/notifications/NotificationEventTracker.ts"() {
2458
2524
  "use strict";
2459
- import_react_native10 = require("react-native");
2525
+ import_react_native11 = require("react-native");
2460
2526
  SEEN_MESSAGES_KEY = "@paywallo:seen_messages";
2461
2527
  LEGACY_SEEN_MESSAGES_KEY = "seen_messages";
2462
2528
  SEEN_TTL_MS = 60 * 60 * 1e3;
@@ -2627,8 +2693,8 @@ var init_NotificationHandlerSetup = __esm({
2627
2693
  // src/core/version.ts
2628
2694
  function resolveVersion() {
2629
2695
  try {
2630
- if ("2.6.0") {
2631
- return "2.6.0";
2696
+ if ("2.6.2") {
2697
+ return "2.6.2";
2632
2698
  }
2633
2699
  } catch {
2634
2700
  }
@@ -2698,7 +2764,7 @@ function mapPermissionStatus(status) {
2698
2764
  }
2699
2765
  }
2700
2766
  function detectPlatform2() {
2701
- return import_react_native11.Platform.OS === "ios" ? "ios" : "android";
2767
+ return import_react_native12.Platform.OS === "ios" ? "ios" : "android";
2702
2768
  }
2703
2769
  async function getAppVersion() {
2704
2770
  try {
@@ -2709,11 +2775,11 @@ async function getAppVersion() {
2709
2775
  return "unknown";
2710
2776
  }
2711
2777
  }
2712
- var import_react_native11, AUTH_STATUS, LOCALE_WHITELIST;
2778
+ var import_react_native12, AUTH_STATUS, LOCALE_WHITELIST;
2713
2779
  var init_utils = __esm({
2714
2780
  "src/domains/notifications/utils.ts"() {
2715
2781
  "use strict";
2716
- import_react_native11 = require("react-native");
2782
+ import_react_native12 = require("react-native");
2717
2783
  init_NotificationsError();
2718
2784
  AUTH_STATUS = {
2719
2785
  NOT_DETERMINED: -1,
@@ -2889,18 +2955,18 @@ function mapPermissionStatus2(status) {
2889
2955
  }
2890
2956
  }
2891
2957
  function getPlatform() {
2892
- return import_react_native12.Platform;
2958
+ return import_react_native13.Platform;
2893
2959
  }
2894
2960
  function needsAndroidRuntimePermission(platform) {
2895
2961
  if (platform.OS !== "android") return false;
2896
2962
  const v = typeof platform.Version === "string" ? parseInt(platform.Version, 10) : platform.Version ?? 0;
2897
2963
  return Number.isFinite(v) && v >= ANDROID_TIRAMISU_API;
2898
2964
  }
2899
- var import_react_native12, AUTH_STATUS2, ANDROID_TIRAMISU_API, PermissionManager;
2965
+ var import_react_native13, AUTH_STATUS2, ANDROID_TIRAMISU_API, PermissionManager;
2900
2966
  var init_PermissionManager = __esm({
2901
2967
  "src/domains/notifications/PermissionManager.ts"() {
2902
2968
  "use strict";
2903
- import_react_native12 = require("react-native");
2969
+ import_react_native13 = require("react-native");
2904
2970
  AUTH_STATUS2 = {
2905
2971
  NOT_DETERMINED: -1,
2906
2972
  DENIED: 0,
@@ -3645,11 +3711,11 @@ function getLocalizedString(text) {
3645
3711
  }
3646
3712
  function detectDeviceLanguage() {
3647
3713
  try {
3648
- if (import_react_native13.Platform.OS === "ios") {
3649
- const settings = import_react_native13.NativeModules.SettingsManager?.settings;
3714
+ if (import_react_native14.Platform.OS === "ios") {
3715
+ const settings = import_react_native14.NativeModules.SettingsManager?.settings;
3650
3716
  return settings?.AppleLocale ?? settings?.AppleLanguages?.[0] ?? "en-US";
3651
3717
  }
3652
- return import_react_native13.NativeModules.I18nManager?.localeIdentifier ?? "en-US";
3718
+ return import_react_native14.NativeModules.I18nManager?.localeIdentifier ?? "en-US";
3653
3719
  } catch {
3654
3720
  return "en-US";
3655
3721
  }
@@ -3671,11 +3737,11 @@ function initLocalization(options) {
3671
3737
  currentLanguage = deviceLanguage;
3672
3738
  }
3673
3739
  }
3674
- var import_react_native13, currentLanguage, defaultLanguage, SDK_STRINGS;
3740
+ var import_react_native14, currentLanguage, defaultLanguage, SDK_STRINGS;
3675
3741
  var init_localization = __esm({
3676
3742
  "src/utils/localization.ts"() {
3677
3743
  "use strict";
3678
- import_react_native13 = require("react-native");
3744
+ import_react_native14 = require("react-native");
3679
3745
  currentLanguage = "pt-BR";
3680
3746
  defaultLanguage = "pt-BR";
3681
3747
  SDK_STRINGS = {
@@ -3712,48 +3778,48 @@ var init_localization = __esm({
3712
3778
 
3713
3779
  // src/domains/paywall/PaywallSkeleton.tsx
3714
3780
  function SkeletonBlock({ style, color, opacity }) {
3715
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native14.Animated.View, { style: [style, { backgroundColor: color, opacity }] });
3781
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native15.Animated.View, { style: [style, { backgroundColor: color, opacity }] });
3716
3782
  }
3717
3783
  function PaywallSkeleton({ backgroundColor = "#FFFFFF" }) {
3718
- const pulse = (0, import_react3.useRef)(new import_react_native14.Animated.Value(0.4)).current;
3784
+ const pulse = (0, import_react3.useRef)(new import_react_native15.Animated.Value(0.4)).current;
3719
3785
  (0, import_react3.useEffect)(() => {
3720
- const loop = import_react_native14.Animated.loop(
3721
- import_react_native14.Animated.sequence([
3722
- import_react_native14.Animated.timing(pulse, { toValue: 1, duration: 700, useNativeDriver: true }),
3723
- import_react_native14.Animated.timing(pulse, { toValue: 0.4, duration: 700, useNativeDriver: true })
3786
+ const loop = import_react_native15.Animated.loop(
3787
+ import_react_native15.Animated.sequence([
3788
+ import_react_native15.Animated.timing(pulse, { toValue: 1, duration: 700, useNativeDriver: true }),
3789
+ import_react_native15.Animated.timing(pulse, { toValue: 0.4, duration: 700, useNativeDriver: true })
3724
3790
  ])
3725
3791
  );
3726
3792
  loop.start();
3727
3793
  return () => loop.stop();
3728
3794
  }, [pulse]);
3729
3795
  const placeholder = isColorDark(backgroundColor) ? "rgba(255,255,255,0.13)" : "rgba(0,0,0,0.07)";
3730
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native14.View, { style: [styles.container, { backgroundColor }], pointerEvents: "none", children: [
3731
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native14.View, { style: styles.header, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.logo, color: placeholder, opacity: pulse }) }),
3796
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native15.View, { style: [styles.container, { backgroundColor }], pointerEvents: "none", children: [
3797
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native15.View, { style: styles.header, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.logo, color: placeholder, opacity: pulse }) }),
3732
3798
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.hero, color: placeholder, opacity: pulse }),
3733
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native14.View, { style: styles.titleGroup, children: [
3799
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native15.View, { style: styles.titleGroup, children: [
3734
3800
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.titleLine, color: placeholder, opacity: pulse }),
3735
3801
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.titleLineShort, color: placeholder, opacity: pulse })
3736
3802
  ] }),
3737
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native14.View, { style: styles.cardsRow, children: [
3803
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native15.View, { style: styles.cardsRow, children: [
3738
3804
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.card, color: placeholder, opacity: pulse }),
3739
3805
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.card, color: placeholder, opacity: pulse })
3740
3806
  ] }),
3741
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native14.View, { style: styles.footerGroup, children: [
3807
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native15.View, { style: styles.footerGroup, children: [
3742
3808
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.cta, color: placeholder, opacity: pulse }),
3743
3809
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.footer, color: placeholder, opacity: pulse })
3744
3810
  ] })
3745
3811
  ] });
3746
3812
  }
3747
- var import_react3, import_react_native14, import_jsx_runtime, RADIUS, styles;
3813
+ var import_react3, import_react_native15, import_jsx_runtime, RADIUS, styles;
3748
3814
  var init_PaywallSkeleton = __esm({
3749
3815
  "src/domains/paywall/PaywallSkeleton.tsx"() {
3750
3816
  "use strict";
3751
3817
  import_react3 = require("react");
3752
- import_react_native14 = require("react-native");
3818
+ import_react_native15 = require("react-native");
3753
3819
  init_extractFirstPageBackground();
3754
3820
  import_jsx_runtime = require("react/jsx-runtime");
3755
3821
  RADIUS = 14;
3756
- styles = import_react_native14.StyleSheet.create({
3822
+ styles = import_react_native15.StyleSheet.create({
3757
3823
  card: { borderRadius: RADIUS, flex: 1, height: 120 },
3758
3824
  cardsRow: { flexDirection: "row", gap: 12, marginTop: "auto", paddingHorizontal: 24 },
3759
3825
  container: { flex: 1, paddingBottom: 40, paddingTop: 64 },
@@ -3819,7 +3885,7 @@ function getNativeWebView() {
3819
3885
  if (NativeWebViewComponent) return NativeWebViewComponent;
3820
3886
  if (nativeWebViewLookupFailed) return null;
3821
3887
  try {
3822
- NativeWebViewComponent = (0, import_react_native15.requireNativeComponent)("PaywalloWebView");
3888
+ NativeWebViewComponent = (0, import_react_native16.requireNativeComponent)("PaywalloWebView");
3823
3889
  return NativeWebViewComponent;
3824
3890
  } catch {
3825
3891
  nativeWebViewLookupFailed = true;
@@ -3828,9 +3894,9 @@ function getNativeWebView() {
3828
3894
  }
3829
3895
  function getWebViewEmitter() {
3830
3896
  if (webViewEmitter) return webViewEmitter;
3831
- const mod = import_react_native15.NativeModules.PaywalloWebViewModule;
3897
+ const mod = import_react_native16.NativeModules.PaywalloWebViewModule;
3832
3898
  if (!mod) return null;
3833
- webViewEmitter = new import_react_native15.NativeEventEmitter(mod);
3899
+ webViewEmitter = new import_react_native16.NativeEventEmitter(mod);
3834
3900
  return webViewEmitter;
3835
3901
  }
3836
3902
  async function triggerNativeHaptic(style) {
@@ -3921,10 +3987,10 @@ function PaywallWebView({
3921
3987
  }
3922
3988
  }, []);
3923
3989
  const injectScript = (0, import_react4.useCallback)((script) => {
3924
- if (import_react_native15.Platform.OS === "android") {
3925
- const handle = (0, import_react_native15.findNodeHandle)(webViewRef.current);
3990
+ if (import_react_native16.Platform.OS === "android") {
3991
+ const handle = (0, import_react_native16.findNodeHandle)(webViewRef.current);
3926
3992
  if (handle == null) return;
3927
- import_react_native15.UIManager.dispatchViewManagerCommand(handle, "injectJavaScript", [script]);
3993
+ import_react_native16.UIManager.dispatchViewManagerCommand(handle, "injectJavaScript", [script]);
3928
3994
  return;
3929
3995
  }
3930
3996
  setScriptToInject(script);
@@ -3984,7 +4050,7 @@ function PaywallWebView({
3984
4050
  if (message.payload?.url) {
3985
4051
  const url = message.payload.url;
3986
4052
  if (/^https?:\/\//i.test(url) || /^mailto:/i.test(url) || /^itms-apps:/i.test(url) || /^market:/i.test(url)) {
3987
- void import_react_native15.Linking.openURL(url);
4053
+ void import_react_native16.Linking.openURL(url);
3988
4054
  }
3989
4055
  }
3990
4056
  break;
@@ -4065,18 +4131,18 @@ function PaywallWebView({
4065
4131
  injectScript(buildPurchaseStateScript(isPurchasing));
4066
4132
  }, [isPurchasing, injectScript]);
4067
4133
  (0, import_react4.useEffect)(() => {
4068
- if (import_react_native15.Platform.OS !== "android") return;
4134
+ if (import_react_native16.Platform.OS !== "android") return;
4069
4135
  const onBackPress = () => {
4070
4136
  if (!paywallDataSent.current) return false;
4071
4137
  injectScript(buildBackButtonScript());
4072
4138
  return true;
4073
4139
  };
4074
- const subscription = import_react_native15.BackHandler.addEventListener("hardwareBackPress", onBackPress);
4140
+ const subscription = import_react_native16.BackHandler.addEventListener("hardwareBackPress", onBackPress);
4075
4141
  return () => subscription.remove();
4076
4142
  }, [injectScript]);
4077
4143
  if (!resolvedWebUrl || !NativeWebView) return null;
4078
4144
  const paywallUrl = `${resolvedWebUrl}/paywall/${paywallId}`;
4079
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native15.View, { style: styles2.container, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4145
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native16.View, { style: styles2.container, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4080
4146
  NativeWebView,
4081
4147
  {
4082
4148
  ref: webViewRef,
@@ -4089,12 +4155,12 @@ function PaywallWebView({
4089
4155
  }
4090
4156
  ) });
4091
4157
  }
4092
- var import_react4, import_react_native15, import_jsx_runtime2, NativeWebViewComponent, nativeWebViewLookupFailed, webViewEmitter, styles2;
4158
+ var import_react4, import_react_native16, import_jsx_runtime2, NativeWebViewComponent, nativeWebViewLookupFailed, webViewEmitter, styles2;
4093
4159
  var init_PaywallWebView = __esm({
4094
4160
  "src/domains/paywall/PaywallWebView.tsx"() {
4095
4161
  "use strict";
4096
4162
  import_react4 = require("react");
4097
- import_react_native15 = require("react-native");
4163
+ import_react_native16 = require("react-native");
4098
4164
  init_PaywalloClient();
4099
4165
  init_parseWebViewMessage();
4100
4166
  init_paywallScripts();
@@ -4102,7 +4168,7 @@ var init_PaywallWebView = __esm({
4102
4168
  NativeWebViewComponent = null;
4103
4169
  nativeWebViewLookupFailed = false;
4104
4170
  webViewEmitter = null;
4105
- styles2 = import_react_native15.StyleSheet.create({
4171
+ styles2 = import_react_native16.StyleSheet.create({
4106
4172
  container: { flex: 1 },
4107
4173
  webview: { flex: 1, backgroundColor: "transparent" }
4108
4174
  });
@@ -4237,7 +4303,7 @@ function mapNativePurchase(native) {
4237
4303
  transactionId: native.transactionId,
4238
4304
  transactionDate: native.transactionDate,
4239
4305
  receipt: native.receipt,
4240
- platform: import_react_native16.Platform.OS
4306
+ platform: import_react_native17.Platform.OS
4241
4307
  };
4242
4308
  }
4243
4309
  function normalizeTransactionUpdate(raw) {
@@ -4257,17 +4323,17 @@ function normalizeTransactionUpdate(raw) {
4257
4323
  if (typeof r.currency === "string") update.currency = r.currency;
4258
4324
  return update;
4259
4325
  }
4260
- var import_react_native16, TRANSACTION_UPDATE_EVENT, PaywalloStoreKitNative, nativeStoreKit, NativeStoreKit;
4326
+ var import_react_native17, TRANSACTION_UPDATE_EVENT, PaywalloStoreKitNative, nativeStoreKit, NativeStoreKit;
4261
4327
  var init_NativeStoreKit = __esm({
4262
4328
  "src/domains/iap/NativeStoreKit.ts"() {
4263
4329
  "use strict";
4264
- import_react_native16 = require("react-native");
4330
+ import_react_native17 = require("react-native");
4265
4331
  init_PaywalloClient();
4266
4332
  init_uuid();
4267
4333
  init_IdentityManager();
4268
4334
  init_PurchaseError();
4269
4335
  TRANSACTION_UPDATE_EVENT = "PaywalloTransactionUpdate";
4270
- PaywalloStoreKitNative = import_react_native16.NativeModules.PaywalloStoreKit ?? null;
4336
+ PaywalloStoreKitNative = import_react_native17.NativeModules.PaywalloStoreKit ?? null;
4271
4337
  nativeStoreKit = {
4272
4338
  isAvailable: isAvailable3,
4273
4339
  async getProducts(productIds) {
@@ -4336,7 +4402,7 @@ var init_NativeStoreKit = __esm({
4336
4402
  subscribeToTransactionUpdates(listener) {
4337
4403
  if (!PaywalloStoreKitNative) return null;
4338
4404
  try {
4339
- const EmitterCtor = import_react_native16.NativeEventEmitter;
4405
+ const EmitterCtor = import_react_native17.NativeEventEmitter;
4340
4406
  const emitter = new EmitterCtor(PaywalloStoreKitNative);
4341
4407
  const sub = emitter.addListener(TRANSACTION_UPDATE_EVENT, (payload) => {
4342
4408
  const update = normalizeTransactionUpdate(payload);
@@ -4969,11 +5035,11 @@ var init_types2 = __esm({
4969
5035
  });
4970
5036
 
4971
5037
  // src/core/network/NetworkMonitor.ts
4972
- var import_react_native17, NetworkMonitorClass, networkMonitor;
5038
+ var import_react_native18, NetworkMonitorClass, networkMonitor;
4973
5039
  var init_NetworkMonitor = __esm({
4974
5040
  "src/core/network/NetworkMonitor.ts"() {
4975
5041
  "use strict";
4976
- import_react_native17 = require("react-native");
5042
+ import_react_native18 = require("react-native");
4977
5043
  init_types2();
4978
5044
  NetworkMonitorClass = class {
4979
5045
  constructor() {
@@ -5002,7 +5068,7 @@ var init_NetworkMonitor = __esm({
5002
5068
  }, this.config.checkInterval);
5003
5069
  }
5004
5070
  setupAppStateListener() {
5005
- this.appStateSubscription = import_react_native17.AppState.addEventListener("change", (state) => {
5071
+ this.appStateSubscription = import_react_native18.AppState.addEventListener("change", (state) => {
5006
5072
  if (state === "active") {
5007
5073
  if (!this.checkIntervalId) {
5008
5074
  this.checkIntervalId = setInterval(() => {
@@ -5371,11 +5437,11 @@ var init_queue = __esm({
5371
5437
  });
5372
5438
 
5373
5439
  // src/domains/iap/IAPValidator.ts
5374
- var import_react_native18, IAPValidator;
5440
+ var import_react_native19, IAPValidator;
5375
5441
  var init_IAPValidator = __esm({
5376
5442
  "src/domains/iap/IAPValidator.ts"() {
5377
5443
  "use strict";
5378
- import_react_native18 = require("react-native");
5444
+ import_react_native19 = require("react-native");
5379
5445
  init_PaywalloClient();
5380
5446
  init_queue();
5381
5447
  init_PurchaseError();
@@ -5401,7 +5467,7 @@ var init_IAPValidator = __esm({
5401
5467
  async validateWithServer(purchase, productId, options) {
5402
5468
  const apiClient = this.getApiClientFn();
5403
5469
  const product = this.getProductFromCache(productId);
5404
- const platform = import_react_native18.Platform.OS;
5470
+ const platform = import_react_native19.Platform.OS;
5405
5471
  const distinctId = PaywalloClient.getDistinctId();
5406
5472
  return this.validateWithRetry(
5407
5473
  () => apiClient.validatePurchase(
@@ -5436,7 +5502,7 @@ var init_IAPValidator = __esm({
5436
5502
  try {
5437
5503
  const apiClient = this.getApiClientFn();
5438
5504
  const product = this.getProductFromCache(productId);
5439
- const platform = import_react_native18.Platform.OS;
5505
+ const platform = import_react_native19.Platform.OS;
5440
5506
  const distinctId = PaywalloClient.getDistinctId();
5441
5507
  const appKey = apiClient.getAppKey();
5442
5508
  const body = {
@@ -5476,11 +5542,11 @@ function getIAPService() {
5476
5542
  }
5477
5543
  return _instance;
5478
5544
  }
5479
- var import_react_native19, IAPService, _instance;
5545
+ var import_react_native20, IAPService, _instance;
5480
5546
  var init_IAPService = __esm({
5481
5547
  "src/domains/iap/IAPService.ts"() {
5482
5548
  "use strict";
5483
- import_react_native19 = require("react-native");
5549
+ import_react_native20 = require("react-native");
5484
5550
  init_PaywalloClient();
5485
5551
  init_IAPTransactionEmitter();
5486
5552
  init_IAPValidator();
@@ -5630,7 +5696,7 @@ var init_IAPService = __esm({
5630
5696
  const transactions = await nativeStoreKit.getActiveTransactions();
5631
5697
  const apiClient = this.getApiClient();
5632
5698
  const distinctId = PaywalloClient.getDistinctId();
5633
- const platform = import_react_native19.Platform.OS;
5699
+ const platform = import_react_native20.Platform.OS;
5634
5700
  const results = await Promise.allSettled(
5635
5701
  transactions.map((tx) => {
5636
5702
  const product = this.productsCache.get(tx.productId);
@@ -5725,7 +5791,7 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
5725
5791
  const [isPurchasing, setIsPurchasing] = (0, import_react6.useState)(false);
5726
5792
  const isPurchasingRef = (0, import_react6.useRef)(false);
5727
5793
  const [isClosing, setIsClosing] = (0, import_react6.useState)(false);
5728
- const slideAnim = (0, import_react6.useRef)(new import_react_native20.Animated.Value(0)).current;
5794
+ const slideAnim = (0, import_react6.useRef)(new import_react_native21.Animated.Value(0)).current;
5729
5795
  const presentedAtRef = (0, import_react6.useRef)(Date.now());
5730
5796
  const closedRef = (0, import_react6.useRef)(false);
5731
5797
  const { trackDismissed, trackProductSelected, trackPurchased } = usePaywallTracking();
@@ -5733,8 +5799,8 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
5733
5799
  if (closedRef.current) return;
5734
5800
  closedRef.current = true;
5735
5801
  const animTarget = openAnim ?? slideAnim;
5736
- import_react_native20.Animated.timing(animTarget, {
5737
- toValue: import_react_native20.Dimensions.get("window").height,
5802
+ import_react_native21.Animated.timing(animTarget, {
5803
+ toValue: import_react_native21.Dimensions.get("window").height,
5738
5804
  duration: 350,
5739
5805
  useNativeDriver: true
5740
5806
  }).start(() => {
@@ -5754,7 +5820,7 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
5754
5820
  closeWithReason("dismissed");
5755
5821
  }, [isClosing, closeWithReason]);
5756
5822
  (0, import_react6.useEffect)(() => {
5757
- const sub = import_react_native20.AppState.addEventListener("change", (nextState) => {
5823
+ const sub = import_react_native21.AppState.addEventListener("change", (nextState) => {
5758
5824
  if (isPurchasingRef.current) return;
5759
5825
  if (nextState === "background" || nextState === "inactive") {
5760
5826
  closeWithReason("backgrounded");
@@ -5822,12 +5888,12 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
5822
5888
  }, [isPurchasing, onResult, paywallConfig, placement, trackDismissed, variantKey, campaignId, variantId]);
5823
5889
  return { isPurchasing, slideAnim, handleClose, handlePurchase, handleRestore };
5824
5890
  }
5825
- var import_react6, import_react_native20, PAYWALL_TIMEOUT_MS;
5891
+ var import_react6, import_react_native21, PAYWALL_TIMEOUT_MS;
5826
5892
  var init_usePaywallActions = __esm({
5827
5893
  "src/domains/paywall/usePaywallActions.ts"() {
5828
5894
  "use strict";
5829
5895
  import_react6 = require("react");
5830
- import_react_native20 = require("react-native");
5896
+ import_react_native21 = require("react-native");
5831
5897
  init_IAPService();
5832
5898
  init_usePaywallTracking();
5833
5899
  PAYWALL_TIMEOUT_MS = 30 * 60 * 1e3;
@@ -5948,11 +6014,11 @@ function ErrorFallback({ description, onRetry, onClose }) {
5948
6014
  const title = overrides?.title ?? getSdkString("paywallErrorTitle");
5949
6015
  const retryLabel = overrides?.retry ?? getSdkString("paywallRetryButton");
5950
6016
  const closeLabel = overrides?.close ?? getSdkString("paywallCloseButton");
5951
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.View, { style: styles3.fallbackContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native21.View, { style: styles3.fallbackCard, children: [
5952
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.fallbackTitle, children: title }),
5953
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.fallbackDescription, children: description }),
5954
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Pressable, { style: styles3.retryButton, onPress: onRetry, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.retryButtonText, children: retryLabel }) }),
5955
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Pressable, { style: styles3.closeButton, onPress: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.closeButtonText, children: closeLabel }) })
6017
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.View, { style: styles3.fallbackContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native22.View, { style: styles3.fallbackCard, children: [
6018
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.Text, { style: styles3.fallbackTitle, children: title }),
6019
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.Text, { style: styles3.fallbackDescription, children: description }),
6020
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.Pressable, { style: styles3.retryButton, onPress: onRetry, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.Text, { style: styles3.retryButtonText, children: retryLabel }) }),
6021
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.Pressable, { style: styles3.closeButton, onPress: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.Text, { style: styles3.closeButtonText, children: closeLabel }) })
5956
6022
  ] }) });
5957
6023
  }
5958
6024
  function PaywallModal({
@@ -5974,8 +6040,8 @@ function PaywallModal({
5974
6040
  campaignId,
5975
6041
  variantId
5976
6042
  );
5977
- const screenHeight = import_react_native21.Dimensions.get("window").height;
5978
- const openAnim = (0, import_react8.useRef)(new import_react_native21.Animated.Value(screenHeight)).current;
6043
+ const screenHeight = import_react_native22.Dimensions.get("window").height;
6044
+ const openAnim = (0, import_react8.useRef)(new import_react_native22.Animated.Value(screenHeight)).current;
5979
6045
  const [modalVisible, setModalVisible] = (0, import_react8.useState)(false);
5980
6046
  const handleResult = (0, import_react8.useCallback)((result) => {
5981
6047
  setModalVisible(false);
@@ -5985,7 +6051,7 @@ function PaywallModal({
5985
6051
  const [webViewError, setWebViewError] = (0, import_react8.useState)(null);
5986
6052
  const [retryCount, setRetryCount] = (0, import_react8.useState)(0);
5987
6053
  const [showSkeleton, setShowSkeleton] = (0, import_react8.useState)(true);
5988
- const skeletonOpacity = (0, import_react8.useRef)(new import_react_native21.Animated.Value(1)).current;
6054
+ const skeletonOpacity = (0, import_react8.useRef)(new import_react_native22.Animated.Value(1)).current;
5989
6055
  const retryCountRef = (0, import_react8.useRef)(0);
5990
6056
  const handleWebViewError = (0, import_react8.useCallback)(
5991
6057
  (err) => {
@@ -6006,10 +6072,10 @@ function PaywallModal({
6006
6072
  skeletonOpacity.setValue(1);
6007
6073
  }, [skeletonOpacity]);
6008
6074
  const handleWebViewReady = (0, import_react8.useCallback)(() => {
6009
- import_react_native21.Animated.timing(skeletonOpacity, {
6075
+ import_react_native22.Animated.timing(skeletonOpacity, {
6010
6076
  toValue: 0,
6011
6077
  duration: 250,
6012
- easing: import_react_native21.Easing.out(import_react_native21.Easing.cubic),
6078
+ easing: import_react_native22.Easing.out(import_react_native22.Easing.cubic),
6013
6079
  useNativeDriver: true
6014
6080
  }).start(() => setShowSkeleton(false));
6015
6081
  }, [skeletonOpacity]);
@@ -6023,11 +6089,11 @@ function PaywallModal({
6023
6089
  setModalVisible(true);
6024
6090
  setShowSkeleton(true);
6025
6091
  skeletonOpacity.setValue(1);
6026
- openAnim.setValue(import_react_native21.Dimensions.get("window").height);
6027
- import_react_native21.Animated.timing(openAnim, {
6092
+ openAnim.setValue(import_react_native22.Dimensions.get("window").height);
6093
+ import_react_native22.Animated.timing(openAnim, {
6028
6094
  toValue: 0,
6029
6095
  duration: 550,
6030
- easing: import_react_native21.Easing.out(import_react_native21.Easing.cubic),
6096
+ easing: import_react_native22.Easing.out(import_react_native22.Easing.cubic),
6031
6097
  useNativeDriver: true
6032
6098
  }).start();
6033
6099
  }
@@ -6035,7 +6101,7 @@ function PaywallModal({
6035
6101
  if (!modalVisible && !visible) return null;
6036
6102
  const skeletonBackground = paywallConfig && "craftData" in paywallConfig.config ? extractFirstPageBackground(paywallConfig.config.craftData) : "#FFFFFF";
6037
6103
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6038
- import_react_native21.Modal,
6104
+ import_react_native22.Modal,
6039
6105
  {
6040
6106
  visible: modalVisible,
6041
6107
  animationType: "none",
@@ -6043,8 +6109,8 @@ function PaywallModal({
6043
6109
  onRequestClose: handleClose,
6044
6110
  transparent: true,
6045
6111
  statusBarTranslucent: true,
6046
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.View, { style: styles3.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Animated.View, { style: [styles3.animatedContainer, { transform: [{ translateY: openAnim }] }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native21.View, { style: styles3.container, children: [
6047
- error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.View, { style: styles3.errorContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native21.Text, { style: styles3.errorText, children: error.message }) }),
6112
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.View, { style: styles3.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.Animated.View, { style: [styles3.animatedContainer, { transform: [{ translateY: openAnim }] }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native22.View, { style: styles3.container, children: [
6113
+ error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.View, { style: styles3.errorContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native22.Text, { style: styles3.errorText, children: error.message }) }),
6048
6114
  !error && paywallConfig && "craftData" in paywallConfig.config && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: webViewError ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6049
6115
  ErrorFallback,
6050
6116
  {
@@ -6071,9 +6137,9 @@ function PaywallModal({
6071
6137
  retryCount
6072
6138
  ) }),
6073
6139
  showSkeleton && !error && !webViewError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6074
- import_react_native21.Animated.View,
6140
+ import_react_native22.Animated.View,
6075
6141
  {
6076
- style: [import_react_native21.StyleSheet.absoluteFill, { opacity: skeletonOpacity }],
6142
+ style: [import_react_native22.StyleSheet.absoluteFill, { opacity: skeletonOpacity }],
6077
6143
  pointerEvents: "none",
6078
6144
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaywallSkeleton, { backgroundColor: skeletonBackground })
6079
6145
  }
@@ -6082,12 +6148,12 @@ function PaywallModal({
6082
6148
  }
6083
6149
  );
6084
6150
  }
6085
- var import_react8, import_react_native21, import_jsx_runtime3, styles3;
6151
+ var import_react8, import_react_native22, import_jsx_runtime3, styles3;
6086
6152
  var init_PaywallModal = __esm({
6087
6153
  "src/domains/paywall/PaywallModal.tsx"() {
6088
6154
  "use strict";
6089
6155
  import_react8 = require("react");
6090
- import_react_native21 = require("react-native");
6156
+ import_react_native22 = require("react-native");
6091
6157
  init_PaywalloClient();
6092
6158
  init_localization();
6093
6159
  init_extractFirstPageBackground();
@@ -6096,7 +6162,7 @@ var init_PaywallModal = __esm({
6096
6162
  init_usePaywallActions();
6097
6163
  init_usePaywallLoader();
6098
6164
  import_jsx_runtime3 = require("react/jsx-runtime");
6099
- styles3 = import_react_native21.StyleSheet.create({
6165
+ styles3 = import_react_native22.StyleSheet.create({
6100
6166
  overlay: { flex: 1, backgroundColor: "rgba(0,0,0,0.3)" },
6101
6167
  animatedContainer: { flex: 1, backgroundColor: "#fff" },
6102
6168
  container: { flex: 1, backgroundColor: "#fff" },
@@ -6266,7 +6332,7 @@ function getNativeWebView2() {
6266
6332
  if (NativeWebViewComponent2) return NativeWebViewComponent2;
6267
6333
  if (nativeLookupFailed) return null;
6268
6334
  try {
6269
- NativeWebViewComponent2 = (0, import_react_native22.requireNativeComponent)("PaywalloWebView");
6335
+ NativeWebViewComponent2 = (0, import_react_native23.requireNativeComponent)("PaywalloWebView");
6270
6336
  return NativeWebViewComponent2;
6271
6337
  } catch {
6272
6338
  nativeLookupFailed = true;
@@ -6289,20 +6355,20 @@ function PaywallWebViewPrewarmer({
6289
6355
  if (PaywalloClient.getConfig()?.debug) {
6290
6356
  console.log(`[Paywallo PREWARM] mounting hidden WebView: ${preheatUrl}`);
6291
6357
  }
6292
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native22.View, { pointerEvents: "none", style: styles4.hidden, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(NativeWebView, { sourceUrl: preheatUrl, style: styles4.fill }) });
6358
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native23.View, { pointerEvents: "none", style: styles4.hidden, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(NativeWebView, { sourceUrl: preheatUrl, style: styles4.fill }) });
6293
6359
  }
6294
- var import_react9, import_react_native22, import_jsx_runtime4, NativeWebViewComponent2, nativeLookupFailed, DEFAULT_DURATION_MS, styles4;
6360
+ var import_react9, import_react_native23, import_jsx_runtime4, NativeWebViewComponent2, nativeLookupFailed, DEFAULT_DURATION_MS, styles4;
6295
6361
  var init_PaywallWebViewPrewarmer = __esm({
6296
6362
  "src/domains/paywall/PaywallWebViewPrewarmer.tsx"() {
6297
6363
  "use strict";
6298
6364
  import_react9 = require("react");
6299
- import_react_native22 = require("react-native");
6365
+ import_react_native23 = require("react-native");
6300
6366
  init_PaywalloClient();
6301
6367
  import_jsx_runtime4 = require("react/jsx-runtime");
6302
6368
  NativeWebViewComponent2 = null;
6303
6369
  nativeLookupFailed = false;
6304
6370
  DEFAULT_DURATION_MS = 60 * 1e3;
6305
- styles4 = import_react_native22.StyleSheet.create({
6371
+ styles4 = import_react_native23.StyleSheet.create({
6306
6372
  hidden: {
6307
6373
  height: 1,
6308
6374
  left: -9999,
@@ -7340,12 +7406,12 @@ async function detectEnvironment() {
7340
7406
  cached = "sandbox";
7341
7407
  return cached;
7342
7408
  }
7343
- if (!nativeModule) {
7409
+ if (!nativeModule2) {
7344
7410
  cached = "production";
7345
7411
  return cached;
7346
7412
  }
7347
7413
  try {
7348
- const result = await nativeModule.detect();
7414
+ const result = await nativeModule2.detect();
7349
7415
  cached = result === "sandbox" ? "sandbox" : "production";
7350
7416
  return cached;
7351
7417
  } catch {
@@ -7353,12 +7419,12 @@ async function detectEnvironment() {
7353
7419
  return cached;
7354
7420
  }
7355
7421
  }
7356
- var import_react_native23, nativeModule, cached;
7422
+ var import_react_native24, nativeModule2, cached;
7357
7423
  var init_detectEnvironment = __esm({
7358
7424
  "src/utils/detectEnvironment.ts"() {
7359
7425
  "use strict";
7360
- import_react_native23 = require("react-native");
7361
- nativeModule = import_react_native23.NativeModules.PaywalloEnv ?? null;
7426
+ import_react_native24 = require("react-native");
7427
+ nativeModule2 = import_react_native24.NativeModules.PaywalloEnv ?? null;
7362
7428
  cached = null;
7363
7429
  }
7364
7430
  });
@@ -7426,6 +7492,32 @@ var init_apiPurchaseMethods = __esm({
7426
7492
  }
7427
7493
  });
7428
7494
 
7495
+ // src/utils/userAgent.ts
7496
+ function buildUserAgent(sdkVersion) {
7497
+ const clean = (v) => v.replace(/[^\x20-\x7E]/g, "").replace(/[();]/g, "").trim();
7498
+ const info = typeof nativeDeviceInfo.getCachedDeviceInfo === "function" ? nativeDeviceInfo.getCachedDeviceInfo() : null;
7499
+ if (!info) {
7500
+ return `PaywalloSDK/${sdkVersion} (${clean(import_react_native25.Platform.OS)})`;
7501
+ }
7502
+ const isValid = (v) => {
7503
+ if (typeof v !== "string") return false;
7504
+ const c = clean(v);
7505
+ return c.length > 0 && c !== "unknown";
7506
+ };
7507
+ const parts = [clean(info.osName)];
7508
+ if (isValid(info.systemVersion)) parts.push(clean(info.systemVersion));
7509
+ const detail = isValid(info.model) ? `; ${clean(info.model)}` : "";
7510
+ return `PaywalloSDK/${sdkVersion} (${parts.join(" ")}${detail})`;
7511
+ }
7512
+ var import_react_native25;
7513
+ var init_userAgent = __esm({
7514
+ "src/utils/userAgent.ts"() {
7515
+ "use strict";
7516
+ import_react_native25 = require("react-native");
7517
+ init_NativeDeviceInfo();
7518
+ }
7519
+ });
7520
+
7429
7521
  // src/core/ApiCache.ts
7430
7522
  var ApiCache;
7431
7523
  var init_ApiCache = __esm({
@@ -7669,6 +7761,11 @@ async function postWithQueue(deps, url, payload, label, priority) {
7669
7761
  priority
7670
7762
  );
7671
7763
  };
7764
+ if (priority === "critical" && deps.isOfflineQueueEnabled()) {
7765
+ await enqueue();
7766
+ if (deps.isDebug()) console.log("[Paywallo:ApiClient] Critical event queued (write-ahead):", label);
7767
+ return;
7768
+ }
7672
7769
  if (deps.isOfflineQueueEnabled() && !networkMonitor.isOnline()) {
7673
7770
  await enqueue();
7674
7771
  if (deps.isDebug()) console.log("[Paywallo:ApiClient] Queued for offline:", label, priority ?? "normal");
@@ -7726,7 +7823,7 @@ function buildV2Envelope(events, providerContext) {
7726
7823
  return { id, ts: event.timestamp, name: family, payload };
7727
7824
  });
7728
7825
  if (context.sdk_version === void 0) context.sdk_version = SDK_VERSION;
7729
- if (context.platform === void 0) context.platform = import_react_native24.Platform.OS;
7826
+ if (context.platform === void 0) context.platform = import_react_native26.Platform.OS;
7730
7827
  if (context.distinct_id === void 0 && events.length > 0) {
7731
7828
  context.distinct_id = events[0].distinctId;
7732
7829
  }
@@ -7784,11 +7881,11 @@ function splitPayloadAndContext(properties) {
7784
7881
  }
7785
7882
  return { payload, promoted };
7786
7883
  }
7787
- var import_react_native24, import_zod2, v2EventSchema, v2ContextSchema, v2EnvelopeSchema, IDS_PROMO_ALIASES, CONTEXT_KEY_ALIASES;
7884
+ var import_react_native26, import_zod2, v2EventSchema, v2ContextSchema, v2EnvelopeSchema, IDS_PROMO_ALIASES, CONTEXT_KEY_ALIASES;
7788
7885
  var init_eventEnvelopeV2 = __esm({
7789
7886
  "src/core/eventEnvelopeV2.ts"() {
7790
7887
  "use strict";
7791
- import_react_native24 = require("react-native");
7888
+ import_react_native26 = require("react-native");
7792
7889
  import_zod2 = require("zod");
7793
7890
  init_uuid();
7794
7891
  init_eventFamilies();
@@ -7866,11 +7963,11 @@ var init_events = __esm({
7866
7963
  });
7867
7964
 
7868
7965
  // src/core/EventBatcher.ts
7869
- var import_react_native25, BATCH_MAX_SIZE, BATCH_FLUSH_MS, EVENT_NAME_REGEX, V2_BATCH_ENDPOINT, EventBatcher;
7966
+ var import_react_native27, BATCH_MAX_SIZE, BATCH_FLUSH_MS, EVENT_NAME_REGEX, V2_BATCH_ENDPOINT, EventBatcher;
7870
7967
  var init_EventBatcher = __esm({
7871
7968
  "src/core/EventBatcher.ts"() {
7872
7969
  "use strict";
7873
- import_react_native25 = require("react-native");
7970
+ import_react_native27 = require("react-native");
7874
7971
  init_eventEnvelopeV2();
7875
7972
  init_events();
7876
7973
  BATCH_MAX_SIZE = 25;
@@ -7879,10 +7976,8 @@ var init_EventBatcher = __esm({
7879
7976
  V2_BATCH_ENDPOINT = "/sdk/ingest/batch";
7880
7977
  EventBatcher = class {
7881
7978
  constructor(post, debug = false, contextProvider = null) {
7882
- this.criticalQueue = [];
7883
7979
  this.normalQueue = [];
7884
7980
  this.normalTimer = null;
7885
- this.criticalScheduled = false;
7886
7981
  this.post = post;
7887
7982
  this.debug = debug;
7888
7983
  this.contextProvider = contextProvider;
@@ -7919,14 +8014,17 @@ var init_EventBatcher = __esm({
7919
8014
  const event = {
7920
8015
  eventName,
7921
8016
  distinctId,
7922
- properties: { ...properties, platform: import_react_native25.Platform.OS },
8017
+ properties: { ...properties, platform: import_react_native27.Platform.OS },
7923
8018
  timestamp: timestamp ?? Date.now(),
7924
8019
  environment: environment.toLowerCase()
7925
8020
  };
7926
8021
  const priority = options?.priority ?? "normal";
7927
8022
  if (priority === "critical") {
7928
- this.criticalQueue.push(event);
7929
- this.scheduleCriticalFlush();
8023
+ try {
8024
+ await this.postBatch([event], `event_critical:${event.eventName}`, "critical");
8025
+ } catch (err) {
8026
+ if (this.debug) console.log("[Paywallo:CRITICAL] critical event post failed", { eventName: event.eventName, error: err instanceof Error ? err.message : String(err) });
8027
+ }
7930
8028
  return;
7931
8029
  }
7932
8030
  this.normalQueue.push(event);
@@ -7947,9 +8045,10 @@ var init_EventBatcher = __esm({
7947
8045
  }
7948
8046
  /**
7949
8047
  * Force flush of the normal queue. Critical events are never held in the
7950
- * normal queue, so this does not affect them (they flush on their own
7951
- * microtask). Exposed so callers (e.g. `AppState=background` listener in
7952
- * phase 2.4) can drain pending events before the app is suspended.
8048
+ * normal queue, so this does not affect them they are posted (and
8049
+ * awaited) synchronously inside `track()`. Exposed so callers (e.g.
8050
+ * `AppState=background` listener in phase 2.4) can drain pending events
8051
+ * before the app is suspended.
7953
8052
  */
7954
8053
  async flush() {
7955
8054
  await this.flushNormal();
@@ -7959,28 +8058,7 @@ var init_EventBatcher = __esm({
7959
8058
  clearTimeout(this.normalTimer);
7960
8059
  this.normalTimer = null;
7961
8060
  }
7962
- this.criticalQueue = [];
7963
8061
  this.normalQueue = [];
7964
- this.criticalScheduled = false;
7965
- }
7966
- scheduleCriticalFlush() {
7967
- if (this.criticalScheduled) return;
7968
- this.criticalScheduled = true;
7969
- queueMicrotask(() => {
7970
- this.criticalScheduled = false;
7971
- void this.flushCritical();
7972
- });
7973
- }
7974
- async flushCritical() {
7975
- if (this.criticalQueue.length === 0) return;
7976
- const drained = this.criticalQueue.splice(0, this.criticalQueue.length);
7977
- for (const event of drained) {
7978
- try {
7979
- await this.postBatch([event], `event_critical:${event.eventName}`, "critical");
7980
- } catch (err) {
7981
- if (this.debug) console.log("[Paywallo:CRITICAL] critical event post failed", { eventName: event.eventName, error: err instanceof Error ? err.message : String(err) });
7982
- }
7983
- }
7984
8062
  }
7985
8063
  async flushNormal() {
7986
8064
  if (this.normalQueue.length === 0) return;
@@ -8265,6 +8343,7 @@ function buildPiiPayload(pii) {
8265
8343
  if (dob) result.dateOfBirth = dob;
8266
8344
  const g = normalizeGender(pii.gender);
8267
8345
  if (g) result.gender = g;
8346
+ if (pii.zipCode) result.zipCode = pii.zipCode.trim();
8268
8347
  return result;
8269
8348
  }
8270
8349
  function normalizeGender(raw) {
@@ -8274,12 +8353,13 @@ function normalizeGender(raw) {
8274
8353
  if (lower === "f" || lower === "female") return "f";
8275
8354
  return void 0;
8276
8355
  }
8277
- var import_react_native26, DATE_OF_BIRTH_RE, ApiClient;
8356
+ var import_react_native28, DATE_OF_BIRTH_RE, ApiClient;
8278
8357
  var init_ApiClient = __esm({
8279
8358
  "src/core/ApiClient.ts"() {
8280
8359
  "use strict";
8281
- import_react_native26 = require("react-native");
8360
+ import_react_native28 = require("react-native");
8282
8361
  init_apiPurchaseMethods();
8362
+ init_userAgent();
8283
8363
  init_ApiCache();
8284
8364
  init_ApiClientFlags();
8285
8365
  init_ApiClientQueue();
@@ -8379,10 +8459,13 @@ var init_ApiClient = __esm({
8379
8459
  * should carry. Keep this tiny — it runs once per ApiClient instance.
8380
8460
  */
8381
8461
  buildSdkHeaders() {
8462
+ const ua = buildUserAgent(SDK_VERSION);
8382
8463
  return {
8383
8464
  "x-sdk-version": SDK_VERSION,
8384
- "x-sdk-platform": import_react_native26.Platform.OS,
8385
- "x-sdk-environment": this.environment
8465
+ "x-sdk-platform": import_react_native28.Platform.OS,
8466
+ "x-sdk-environment": this.environment,
8467
+ "User-Agent": ua,
8468
+ "x-sdk-user-agent": ua
8386
8469
  };
8387
8470
  }
8388
8471
  async clearQueue() {
@@ -8411,7 +8494,7 @@ var init_ApiClient = __esm({
8411
8494
  message,
8412
8495
  context,
8413
8496
  sdkVersion: SDK_VERSION,
8414
- platform: import_react_native26.Platform.OS
8497
+ platform: import_react_native28.Platform.OS
8415
8498
  }, true);
8416
8499
  } catch (err) {
8417
8500
  if (this.debug) console.log("[Paywallo:ApiClient] reportError failed", err);
@@ -8429,7 +8512,7 @@ var init_ApiClient = __esm({
8429
8512
  async identify(distinctId, properties, email, deviceId, pii) {
8430
8513
  const rawTraits = {
8431
8514
  email: email || void 0,
8432
- platform: import_react_native26.Platform.OS,
8515
+ platform: import_react_native28.Platform.OS,
8433
8516
  name: properties?.name,
8434
8517
  country: properties?.country,
8435
8518
  locale: properties?.locale,
@@ -8840,9 +8923,14 @@ async function doInit(state, config) {
8840
8923
  } catch (err) {
8841
8924
  if (config.debug) console.log("[Paywallo ATTR] start error", err);
8842
8925
  }
8843
- void nativeDeviceInfo.getDeviceInfo().catch(() => null);
8844
- void advertisingIdManager.collect(false).catch(() => null);
8845
- void metaBridge.getAnonymousID().catch(() => null);
8926
+ await Promise.race([
8927
+ Promise.all([
8928
+ nativeDeviceInfo.getDeviceInfo().catch(() => null),
8929
+ advertisingIdManager.collect(false).catch(() => null),
8930
+ metaBridge.getAnonymousID().catch(() => null)
8931
+ ]),
8932
+ new Promise((resolve) => setTimeout(resolve, 350))
8933
+ ]);
8846
8934
  apiClient.setEventContextProvider(() => {
8847
8935
  const attr = attributionTracker.get();
8848
8936
  const attrEntries = attr ? [
@@ -8879,10 +8967,10 @@ async function doInit(state, config) {
8879
8967
  let screenHeight;
8880
8968
  let screenDensity;
8881
8969
  try {
8882
- const screen = import_react_native27.Dimensions.get("screen");
8970
+ const screen = import_react_native29.Dimensions.get("screen");
8883
8971
  screenWidth = Math.round(screen.width) || void 0;
8884
8972
  screenHeight = Math.round(screen.height) || void 0;
8885
- screenDensity = import_react_native27.PixelRatio.get() || void 0;
8973
+ screenDensity = import_react_native29.PixelRatio.get() || void 0;
8886
8974
  } catch {
8887
8975
  }
8888
8976
  return {
@@ -8952,11 +9040,11 @@ async function doInit(state, config) {
8952
9040
  setupAutoPreload(state, apiClient, config, distinctId);
8953
9041
  startBatchPreload(apiClient, config.debug);
8954
9042
  }
8955
- var import_react_native27;
9043
+ var import_react_native29;
8956
9044
  var init_PaywalloInitializer = __esm({
8957
9045
  "src/core/PaywalloInitializer.ts"() {
8958
9046
  "use strict";
8959
- import_react_native27 = require("react-native");
9047
+ import_react_native29 = require("react-native");
8960
9048
  init_identity();
8961
9049
  init_AdvertisingIdManager();
8962
9050
  init_DeepLinkAttributionCapture();
@@ -9398,7 +9486,7 @@ __export(OfferingService_exports, {
9398
9486
  offeringService: () => offeringService
9399
9487
  });
9400
9488
  function resolveProductId(raw) {
9401
- const isIos = import_react_native28.Platform.OS === "ios";
9489
+ const isIos = import_react_native30.Platform.OS === "ios";
9402
9490
  const productId = isIos ? raw.apple_product_id : raw.google_product_id;
9403
9491
  return productId ?? "";
9404
9492
  }
@@ -9417,7 +9505,7 @@ function mapProduct2(raw) {
9417
9505
  };
9418
9506
  }
9419
9507
  function pickPlatformProduct(products) {
9420
- const isIos = import_react_native28.Platform.OS === "ios";
9508
+ const isIos = import_react_native30.Platform.OS === "ios";
9421
9509
  const match = products.find((p) => isIos ? p.apple_product_id : p.google_product_id);
9422
9510
  return match ?? products[0] ?? null;
9423
9511
  }
@@ -9433,11 +9521,11 @@ function mapOffering(raw) {
9433
9521
  product: mapProduct2(rawProduct)
9434
9522
  };
9435
9523
  }
9436
- var import_react_native28, OFFERINGS_CACHE_KEY, DEFAULT_TTL3, OfferingService, offeringService;
9524
+ var import_react_native30, OFFERINGS_CACHE_KEY, DEFAULT_TTL3, OfferingService, offeringService;
9437
9525
  var init_OfferingService = __esm({
9438
9526
  "src/domains/offering/OfferingService.ts"() {
9439
9527
  "use strict";
9440
- import_react_native28 = require("react-native");
9528
+ import_react_native30 = require("react-native");
9441
9529
  init_SecureStorage();
9442
9530
  OFFERINGS_CACHE_KEY = "@paywallo:offerings_cache";
9443
9531
  DEFAULT_TTL3 = 5 * 60 * 1e3;
@@ -10099,7 +10187,7 @@ function useSubscription() {
10099
10187
 
10100
10188
  // src/PaywalloProvider.tsx
10101
10189
  var import_react28 = require("react");
10102
- var import_react_native29 = require("react-native");
10190
+ var import_react_native31 = require("react-native");
10103
10191
  init_PaywalloClient();
10104
10192
  init_NativeStorage();
10105
10193
  init_SecureStorage();
@@ -10991,8 +11079,8 @@ function PaywalloProvider({ children, config }) {
10991
11079
  });
10992
11080
  }, []);
10993
11081
  const { showingPreloadedWebView, presentPreloadedWebView, resolvePreloadedPaywall, handlePreloadedWebViewReady: baseHandlePreloadedWebViewReady, handlePreloadedClose: baseHandlePreloadedClose, setShowingPreloadedWebView, presentedAtRef } = usePaywallPresenter(preloadedWebView, setPreloadedWebView);
10994
- const SCREEN_HEIGHT = (0, import_react28.useMemo)(() => import_react_native29.Dimensions.get("window").height, []);
10995
- const slideAnim = (0, import_react28.useRef)(new import_react_native29.Animated.Value(SCREEN_HEIGHT)).current;
11082
+ const SCREEN_HEIGHT = (0, import_react28.useMemo)(() => import_react_native31.Dimensions.get("window").height, []);
11083
+ const slideAnim = (0, import_react28.useRef)(new import_react_native31.Animated.Value(SCREEN_HEIGHT)).current;
10996
11084
  const handlePreloadedWebViewReady = (0, import_react28.useCallback)(() => {
10997
11085
  if (PaywalloClient.getConfig()?.debug) {
10998
11086
  console.log(`[Paywallo WEBVIEW] loaded \u2014 placement: ${preloadedWebView?.placement}`);
@@ -11001,7 +11089,7 @@ function PaywalloProvider({ children, config }) {
11001
11089
  }, [preloadedWebView?.placement, baseHandlePreloadedWebViewReady]);
11002
11090
  const handlePreloadedClose = (0, import_react28.useCallback)(() => {
11003
11091
  const placement = preloadedWebView?.placement;
11004
- import_react_native29.Animated.timing(slideAnim, { toValue: SCREEN_HEIGHT, duration: 200, easing: import_react_native29.Easing.in(import_react_native29.Easing.cubic), useNativeDriver: true }).start(() => {
11092
+ import_react_native31.Animated.timing(slideAnim, { toValue: SCREEN_HEIGHT, duration: 200, easing: import_react_native31.Easing.in(import_react_native31.Easing.cubic), useNativeDriver: true }).start(() => {
11005
11093
  baseHandlePreloadedClose();
11006
11094
  if (placement) triggerRepreload(placement);
11007
11095
  });
@@ -11286,7 +11374,7 @@ function PaywalloProvider({ children, config }) {
11286
11374
  (0, import_react28.useLayoutEffect)(() => {
11287
11375
  if (showingPreloadedWebView) {
11288
11376
  slideAnim.setValue(SCREEN_HEIGHT);
11289
- import_react_native29.Animated.timing(slideAnim, { toValue: 0, duration: 200, easing: import_react_native29.Easing.out(import_react_native29.Easing.cubic), useNativeDriver: true }).start();
11377
+ import_react_native31.Animated.timing(slideAnim, { toValue: 0, duration: 200, easing: import_react_native31.Easing.out(import_react_native31.Easing.cubic), useNativeDriver: true }).start();
11290
11378
  }
11291
11379
  }, [showingPreloadedWebView, slideAnim, SCREEN_HEIGHT]);
11292
11380
  const preloadStyle = [
@@ -11296,7 +11384,7 @@ function PaywalloProvider({ children, config }) {
11296
11384
  ];
11297
11385
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(PaywalloContext.Provider, { value: contextValue, children: [
11298
11386
  children,
11299
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaywallErrorBoundary, { children: !!preloadedWebView?.craftData && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native29.Animated.View, { style: preloadStyle, pointerEvents: showingPreloadedWebView ? "auto" : "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
11387
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaywallErrorBoundary, { children: !!preloadedWebView?.craftData && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native31.Animated.View, { style: preloadStyle, pointerEvents: showingPreloadedWebView ? "auto" : "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
11300
11388
  PaywallWebView,
11301
11389
  {
11302
11390
  paywallId: preloadedWebView.paywallId,
@@ -11328,7 +11416,7 @@ function PaywalloProvider({ children, config }) {
11328
11416
  isInitialized && (config.preloadPaywalls?.length ?? 0) > 0 && PaywalloClient.getWebUrl() !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaywallWebViewPrewarmer, { webUrl: PaywalloClient.getWebUrl() })
11329
11417
  ] });
11330
11418
  }
11331
- var styles5 = import_react_native29.StyleSheet.create({
11419
+ var styles5 = import_react_native31.StyleSheet.create({
11332
11420
  preloadOverlay: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, backgroundColor: "#ffffff" },
11333
11421
  hidden: { zIndex: -1, opacity: 0, width: 1, height: 1, overflow: "hidden" },
11334
11422
  visible: { zIndex: 9999, opacity: 1 }