@virex-tech/paywallo-sdk 2.5.3 → 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/README.md +11 -0
- package/android/build.gradle +2 -1
- package/android/src/main/AndroidManifest.xml +7 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloAdvertisingIdModule.kt +55 -0
- package/android/src/main/java/com/paywallo/sdk/PaywalloSdkPackage.kt +3 -2
- package/android/src/main/java/com/paywallo/sdk/PaywalloStoreKitModule.kt +10 -3
- package/dist/index.d.mts +36 -31
- package/dist/index.d.ts +36 -31
- package/dist/index.js +352 -258
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +232 -139
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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,11 +668,15 @@ 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
|
});
|
|
674
|
+
if (this.debug) console.log("[Paywallo] identify confirmed", this.anonId.slice(0, 8));
|
|
667
675
|
} catch (err) {
|
|
668
|
-
if (this.debug) console.log("[Paywallo] identify
|
|
676
|
+
if (this.debug) console.log("[Paywallo] identify failed:", err);
|
|
669
677
|
}
|
|
678
|
+
} else {
|
|
679
|
+
if (this.debug) console.log("[Paywallo] identify skipped \u2014 anonId not ready");
|
|
670
680
|
}
|
|
671
681
|
}
|
|
672
682
|
getDistinctId() {
|
|
@@ -709,6 +719,7 @@ var init_IdentityManager = __esm({
|
|
|
709
719
|
this.lastName = null;
|
|
710
720
|
this.dateOfBirth = null;
|
|
711
721
|
this.gender = null;
|
|
722
|
+
this.zipCode = null;
|
|
712
723
|
await Promise.all([
|
|
713
724
|
this.secureStorage?.set(ANON_ID_KEY, newAnonId) ?? Promise.resolve(false),
|
|
714
725
|
this.secureStorage?.remove(USER_EMAIL_KEY) ?? Promise.resolve(false),
|
|
@@ -717,7 +728,8 @@ var init_IdentityManager = __esm({
|
|
|
717
728
|
this.secureStorage?.remove(USER_FIRST_NAME_KEY) ?? Promise.resolve(false),
|
|
718
729
|
this.secureStorage?.remove(USER_LAST_NAME_KEY) ?? Promise.resolve(false),
|
|
719
730
|
this.secureStorage?.remove(USER_DOB_KEY) ?? Promise.resolve(false),
|
|
720
|
-
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)
|
|
721
733
|
]);
|
|
722
734
|
}
|
|
723
735
|
getState() {
|
|
@@ -729,7 +741,8 @@ var init_IdentityManager = __esm({
|
|
|
729
741
|
firstName: this.firstName,
|
|
730
742
|
lastName: this.lastName,
|
|
731
743
|
dateOfBirth: this.dateOfBirth,
|
|
732
|
-
gender: this.gender
|
|
744
|
+
gender: this.gender,
|
|
745
|
+
zipCode: this.zipCode
|
|
733
746
|
};
|
|
734
747
|
}
|
|
735
748
|
isSecureStorageAvailable() {
|
|
@@ -947,17 +960,39 @@ var init_campaign = __esm({
|
|
|
947
960
|
}
|
|
948
961
|
});
|
|
949
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
|
+
|
|
950
982
|
// src/domains/identity/AdvertisingIdManager.ts
|
|
951
|
-
var
|
|
983
|
+
var import_react_native4, ZERO_IDFA, ATT_PROMPT_TIMEOUT_MS, AdvertisingIdManager, advertisingIdManager;
|
|
952
984
|
var init_AdvertisingIdManager = __esm({
|
|
953
985
|
"src/domains/identity/AdvertisingIdManager.ts"() {
|
|
954
986
|
"use strict";
|
|
955
|
-
|
|
987
|
+
import_react_native4 = require("react-native");
|
|
956
988
|
init_NativeDeviceInfo();
|
|
989
|
+
init_NativeAdvertisingId();
|
|
957
990
|
ZERO_IDFA = "00000000-0000-0000-0000-000000000000";
|
|
991
|
+
ATT_PROMPT_TIMEOUT_MS = 4e3;
|
|
958
992
|
AdvertisingIdManager = class {
|
|
959
|
-
constructor() {
|
|
993
|
+
constructor(debug = false) {
|
|
960
994
|
this.cached = null;
|
|
995
|
+
this.debug = debug;
|
|
961
996
|
}
|
|
962
997
|
/**
|
|
963
998
|
* Synchronous accessor for the cached collect() result. Returns null until
|
|
@@ -972,9 +1007,12 @@ var init_AdvertisingIdManager = __esm({
|
|
|
972
1007
|
return this.cached;
|
|
973
1008
|
}
|
|
974
1009
|
const fallback = { idfv: null, idfa: null, gaid: null, attStatus: "unavailable" };
|
|
1010
|
+
if (import_react_native4.Platform.OS === "android") {
|
|
1011
|
+
return this.collectAndroid();
|
|
1012
|
+
}
|
|
975
1013
|
try {
|
|
976
1014
|
const tracking = await import("expo-tracking-transparency");
|
|
977
|
-
if (
|
|
1015
|
+
if (import_react_native4.Platform.OS === "ios") {
|
|
978
1016
|
if (!tracking.isAvailable()) {
|
|
979
1017
|
const idfv2 = await this.collectIdfv();
|
|
980
1018
|
const result2 = { ...fallback, idfv: idfv2 };
|
|
@@ -985,9 +1023,20 @@ var init_AdvertisingIdManager = __esm({
|
|
|
985
1023
|
let status = current.status;
|
|
986
1024
|
let granted = current.granted;
|
|
987
1025
|
if (status === "undetermined" && requestATT) {
|
|
988
|
-
const result2 = await
|
|
989
|
-
|
|
990
|
-
|
|
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
|
+
}
|
|
991
1040
|
}
|
|
992
1041
|
const idfv = await this.collectIdfv();
|
|
993
1042
|
const idfa = granted ? this.sanitizeId(tracking.getAdvertisingId()) : null;
|
|
@@ -995,12 +1044,6 @@ var init_AdvertisingIdManager = __esm({
|
|
|
995
1044
|
if (idfv !== null) this.cached = result;
|
|
996
1045
|
return result;
|
|
997
1046
|
}
|
|
998
|
-
if (import_react_native3.Platform.OS === "android") {
|
|
999
|
-
const rawGaid = tracking.getAdvertisingId();
|
|
1000
|
-
const gaid = this.sanitizeId(rawGaid);
|
|
1001
|
-
this.cached = { idfv: null, idfa: null, gaid, attStatus: "unavailable" };
|
|
1002
|
-
return this.cached;
|
|
1003
|
-
}
|
|
1004
1047
|
this.cached = fallback;
|
|
1005
1048
|
return this.cached;
|
|
1006
1049
|
} catch {
|
|
@@ -1008,6 +1051,27 @@ var init_AdvertisingIdManager = __esm({
|
|
|
1008
1051
|
return this.cached;
|
|
1009
1052
|
}
|
|
1010
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
|
+
}
|
|
1011
1075
|
async collectIdfv() {
|
|
1012
1076
|
const RETRY_DELAY_MS = 80;
|
|
1013
1077
|
const MAX_ATTEMPTS = 3;
|
|
@@ -1151,11 +1215,11 @@ var init_sessionTracking = __esm({
|
|
|
1151
1215
|
});
|
|
1152
1216
|
|
|
1153
1217
|
// src/domains/session/SessionManager.ts
|
|
1154
|
-
var
|
|
1218
|
+
var import_react_native5, SESSION_ID_KEY, SESSION_START_KEY, LEGACY_SESSION_ID_KEY, LEGACY_SESSION_START_KEY, SESSION_TIMEOUT_MS, SessionManager, sessionManager;
|
|
1155
1219
|
var init_SessionManager = __esm({
|
|
1156
1220
|
"src/domains/session/SessionManager.ts"() {
|
|
1157
1221
|
"use strict";
|
|
1158
|
-
|
|
1222
|
+
import_react_native5 = require("react-native");
|
|
1159
1223
|
init_SecureStorage();
|
|
1160
1224
|
init_uuid();
|
|
1161
1225
|
init_distinctIdGuard();
|
|
@@ -1311,7 +1375,7 @@ var init_SessionManager = __esm({
|
|
|
1311
1375
|
if (this.appStateSubscription) {
|
|
1312
1376
|
this.appStateSubscription.remove();
|
|
1313
1377
|
}
|
|
1314
|
-
this.appStateSubscription =
|
|
1378
|
+
this.appStateSubscription = import_react_native5.AppState.addEventListener("change", this.handleAppStateChange);
|
|
1315
1379
|
}
|
|
1316
1380
|
async handleForeground() {
|
|
1317
1381
|
const elapsed = this.backgroundTimestamp ? Date.now() - this.backgroundTimestamp : null;
|
|
@@ -1614,13 +1678,13 @@ var init_deferredAppLink = __esm({
|
|
|
1614
1678
|
});
|
|
1615
1679
|
|
|
1616
1680
|
// src/domains/identity/MetaBridge.ts
|
|
1617
|
-
var
|
|
1681
|
+
var import_react_native6, TIMEOUT_MS, NativeBridge, MetaBridge, metaBridge;
|
|
1618
1682
|
var init_MetaBridge = __esm({
|
|
1619
1683
|
"src/domains/identity/MetaBridge.ts"() {
|
|
1620
1684
|
"use strict";
|
|
1621
|
-
|
|
1685
|
+
import_react_native6 = require("react-native");
|
|
1622
1686
|
TIMEOUT_MS = 2e3;
|
|
1623
|
-
NativeBridge =
|
|
1687
|
+
NativeBridge = import_react_native6.NativeModules.PaywalloFBBridge ?? null;
|
|
1624
1688
|
MetaBridge = class {
|
|
1625
1689
|
constructor() {
|
|
1626
1690
|
this.cachedAnonId = null;
|
|
@@ -1712,18 +1776,18 @@ var init_MetaBridge = __esm({
|
|
|
1712
1776
|
});
|
|
1713
1777
|
|
|
1714
1778
|
// src/domains/identity/InstallReferrerManager.ts
|
|
1715
|
-
var
|
|
1779
|
+
var import_react_native7, REFERRER_TIMEOUT_MS, InstallReferrerManager, installReferrerManager;
|
|
1716
1780
|
var init_InstallReferrerManager = __esm({
|
|
1717
1781
|
"src/domains/identity/InstallReferrerManager.ts"() {
|
|
1718
1782
|
"use strict";
|
|
1719
|
-
|
|
1783
|
+
import_react_native7 = require("react-native");
|
|
1720
1784
|
init_NativeDeviceInfo();
|
|
1721
1785
|
init_deferredAppLink();
|
|
1722
1786
|
init_MetaBridge();
|
|
1723
1787
|
REFERRER_TIMEOUT_MS = 5e3;
|
|
1724
1788
|
InstallReferrerManager = class {
|
|
1725
1789
|
async getReferrer() {
|
|
1726
|
-
if (
|
|
1790
|
+
if (import_react_native7.Platform.OS !== "android") {
|
|
1727
1791
|
return this.fetchDeferredReferrer();
|
|
1728
1792
|
}
|
|
1729
1793
|
let timerId;
|
|
@@ -1829,11 +1893,11 @@ function extractDeferredAttribution(raw) {
|
|
|
1829
1893
|
}
|
|
1830
1894
|
return Object.keys(out).length > 0 ? out : null;
|
|
1831
1895
|
}
|
|
1832
|
-
var
|
|
1896
|
+
var import_react_native8, InstallTracker, DEFERRED_ATTRIBUTION_FIELDS;
|
|
1833
1897
|
var init_InstallTracker = __esm({
|
|
1834
1898
|
"src/domains/identity/InstallTracker.ts"() {
|
|
1835
1899
|
"use strict";
|
|
1836
|
-
|
|
1900
|
+
import_react_native8 = require("react-native");
|
|
1837
1901
|
init_SecureStorage();
|
|
1838
1902
|
init_NativeDeviceInfo();
|
|
1839
1903
|
init_distinctIdGuard();
|
|
@@ -1889,10 +1953,10 @@ var init_InstallTracker = __esm({
|
|
|
1889
1953
|
}
|
|
1890
1954
|
let deviceData = {};
|
|
1891
1955
|
try {
|
|
1892
|
-
const screen =
|
|
1956
|
+
const screen = import_react_native8.Dimensions.get("screen");
|
|
1893
1957
|
const screenWidth = Math.round(screen.width ?? 0);
|
|
1894
1958
|
const screenHeight = Math.round(screen.height ?? 0);
|
|
1895
|
-
const screenDensity =
|
|
1959
|
+
const screenDensity = import_react_native8.PixelRatio.get();
|
|
1896
1960
|
const locale = Intl.DateTimeFormat().resolvedOptions().locale ?? "unknown";
|
|
1897
1961
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone ?? "unknown";
|
|
1898
1962
|
const info = await nativeDeviceInfo.getDeviceInfo();
|
|
@@ -1953,13 +2017,14 @@ var init_InstallTracker = __esm({
|
|
|
1953
2017
|
} else {
|
|
1954
2018
|
const { generateUUID: generateUUID2 } = await Promise.resolve().then(() => (init_uuid(), uuid_exports));
|
|
1955
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_)");
|
|
1956
2021
|
await storage.set(INSTALL_KEYS.ANON_ID, effectiveAnonId).catch(() => {
|
|
1957
2022
|
});
|
|
1958
2023
|
}
|
|
1959
2024
|
}
|
|
1960
2025
|
await apiClient.trackEvent("$app_installed", distinctId, {
|
|
1961
2026
|
installedAt,
|
|
1962
|
-
platform:
|
|
2027
|
+
platform: import_react_native8.Platform.OS,
|
|
1963
2028
|
installEventId,
|
|
1964
2029
|
...sessionId && { sessionId },
|
|
1965
2030
|
...deviceData,
|
|
@@ -1981,11 +2046,11 @@ var init_InstallTracker = __esm({
|
|
|
1981
2046
|
...adIds.gaid && { gaid: adIds.gaid },
|
|
1982
2047
|
attStatus: adIds.attStatus
|
|
1983
2048
|
}, void 0, { priority: "critical" });
|
|
1984
|
-
void this.callDeferredMatch(apiClient, deviceData, adIds, effectiveAnonId, installedAt).catch(() => {
|
|
2049
|
+
void this.callDeferredMatch(apiClient, distinctId, deviceData, adIds, effectiveAnonId, installedAt).catch(() => {
|
|
1985
2050
|
});
|
|
1986
2051
|
await markInstallTracked(storage, installedAt);
|
|
1987
2052
|
}
|
|
1988
|
-
async callDeferredMatch(apiClient, deviceData, adIds, anonId, installedAt) {
|
|
2053
|
+
async callDeferredMatch(apiClient, distinctId, deviceData, adIds, anonId, installedAt) {
|
|
1989
2054
|
const storage = new SecureStorage(this.debug);
|
|
1990
2055
|
const alreadyMatched = await storage.get(INSTALL_KEYS.DEFERRED_MATCH_DONE);
|
|
1991
2056
|
if (alreadyMatched) return;
|
|
@@ -1999,7 +2064,11 @@ var init_InstallTracker = __esm({
|
|
|
1999
2064
|
method: "POST",
|
|
2000
2065
|
headers: { "Content-Type": "application/json", "X-App-Key": appKey },
|
|
2001
2066
|
body: JSON.stringify({
|
|
2002
|
-
platform:
|
|
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,
|
|
2003
2072
|
...adIds.idfv && { idfv: adIds.idfv },
|
|
2004
2073
|
...adIds.gaid && { gaid: adIds.gaid },
|
|
2005
2074
|
...referrer.rawReferrer && { installReferrer: referrer.rawReferrer },
|
|
@@ -2094,11 +2163,11 @@ function parseAttributionFromUrl(url) {
|
|
|
2094
2163
|
return {};
|
|
2095
2164
|
}
|
|
2096
2165
|
}
|
|
2097
|
-
var
|
|
2166
|
+
var import_react_native9, DeepLinkAttributionCapture, deepLinkAttributionCapture;
|
|
2098
2167
|
var init_DeepLinkAttributionCapture = __esm({
|
|
2099
2168
|
"src/domains/identity/DeepLinkAttributionCapture.ts"() {
|
|
2100
2169
|
"use strict";
|
|
2101
|
-
|
|
2170
|
+
import_react_native9 = require("react-native");
|
|
2102
2171
|
init_InstallTracker();
|
|
2103
2172
|
DeepLinkAttributionCapture = class {
|
|
2104
2173
|
constructor(debug = false) {
|
|
@@ -2107,7 +2176,7 @@ var init_DeepLinkAttributionCapture = __esm({
|
|
|
2107
2176
|
}
|
|
2108
2177
|
async start() {
|
|
2109
2178
|
try {
|
|
2110
|
-
const initialUrl = await
|
|
2179
|
+
const initialUrl = await import_react_native9.Linking.getInitialURL();
|
|
2111
2180
|
const parsed = parseAttributionFromUrl(initialUrl);
|
|
2112
2181
|
await attributionTracker.capture(parsed).catch(() => {
|
|
2113
2182
|
});
|
|
@@ -2120,13 +2189,13 @@ var init_DeepLinkAttributionCapture = __esm({
|
|
|
2120
2189
|
void attributionTracker.capture(parsed).catch(() => {
|
|
2121
2190
|
});
|
|
2122
2191
|
};
|
|
2123
|
-
const maybeSub =
|
|
2192
|
+
const maybeSub = import_react_native9.Linking.addEventListener("url", handler);
|
|
2124
2193
|
if (maybeSub && typeof maybeSub.remove === "function") {
|
|
2125
2194
|
this.subscription = maybeSub;
|
|
2126
2195
|
} else {
|
|
2127
2196
|
this.subscription = {
|
|
2128
2197
|
remove: () => {
|
|
2129
|
-
const legacy =
|
|
2198
|
+
const legacy = import_react_native9.Linking;
|
|
2130
2199
|
legacy.removeEventListener?.("url", handler);
|
|
2131
2200
|
}
|
|
2132
2201
|
};
|
|
@@ -2161,10 +2230,10 @@ var init_identity = __esm({
|
|
|
2161
2230
|
|
|
2162
2231
|
// src/domains/notifications/bridges/NativePushBridge.ts
|
|
2163
2232
|
function getPaywalloNotifications() {
|
|
2164
|
-
return
|
|
2233
|
+
return import_react_native10.NativeModules.PaywalloNotifications ?? null;
|
|
2165
2234
|
}
|
|
2166
2235
|
function isNativePushAvailable() {
|
|
2167
|
-
return !!
|
|
2236
|
+
return !!import_react_native10.NativeModules.PaywalloNotifications;
|
|
2168
2237
|
}
|
|
2169
2238
|
function mapStatusToNumber(status) {
|
|
2170
2239
|
switch (status) {
|
|
@@ -2186,16 +2255,16 @@ function mapStatusToNumber(status) {
|
|
|
2186
2255
|
}
|
|
2187
2256
|
function getEmitter() {
|
|
2188
2257
|
if (_emitter) return _emitter;
|
|
2189
|
-
const nativeMod =
|
|
2258
|
+
const nativeMod = import_react_native10.NativeModules.PaywalloNotifications;
|
|
2190
2259
|
if (!nativeMod) return null;
|
|
2191
|
-
_emitter = new
|
|
2260
|
+
_emitter = new import_react_native10.NativeEventEmitter(nativeMod);
|
|
2192
2261
|
return _emitter;
|
|
2193
2262
|
}
|
|
2194
|
-
var
|
|
2263
|
+
var import_react_native10, _emitter, NativePushBridge;
|
|
2195
2264
|
var init_NativePushBridge = __esm({
|
|
2196
2265
|
"src/domains/notifications/bridges/NativePushBridge.ts"() {
|
|
2197
2266
|
"use strict";
|
|
2198
|
-
|
|
2267
|
+
import_react_native10 = require("react-native");
|
|
2199
2268
|
_emitter = null;
|
|
2200
2269
|
NativePushBridge = class {
|
|
2201
2270
|
async getToken() {
|
|
@@ -2208,7 +2277,7 @@ var init_NativePushBridge = __esm({
|
|
|
2208
2277
|
}
|
|
2209
2278
|
}
|
|
2210
2279
|
async getAPNSToken() {
|
|
2211
|
-
if (
|
|
2280
|
+
if (import_react_native10.Platform.OS !== "ios") return null;
|
|
2212
2281
|
return this.getToken();
|
|
2213
2282
|
}
|
|
2214
2283
|
async requestPermission(options) {
|
|
@@ -2301,18 +2370,15 @@ var init_constants = __esm({
|
|
|
2301
2370
|
});
|
|
2302
2371
|
|
|
2303
2372
|
// src/domains/notifications/config.ts
|
|
2304
|
-
function resolveApiBaseUrl(
|
|
2305
|
-
if (config.apiBaseUrl) return config.apiBaseUrl;
|
|
2306
|
-
if (config.environment === "sandbox") return SANDBOX_API_BASE_URL;
|
|
2373
|
+
function resolveApiBaseUrl() {
|
|
2307
2374
|
return DEFAULT_API_BASE_URL;
|
|
2308
2375
|
}
|
|
2309
|
-
var DEFAULT_API_BASE_URL
|
|
2376
|
+
var DEFAULT_API_BASE_URL;
|
|
2310
2377
|
var init_config = __esm({
|
|
2311
2378
|
"src/domains/notifications/config.ts"() {
|
|
2312
2379
|
"use strict";
|
|
2313
2380
|
init_constants();
|
|
2314
2381
|
DEFAULT_API_BASE_URL = DEFAULT_API_URL;
|
|
2315
|
-
SANDBOX_API_BASE_URL = DEFAULT_API_URL;
|
|
2316
2382
|
}
|
|
2317
2383
|
});
|
|
2318
2384
|
|
|
@@ -2450,13 +2516,13 @@ function getTimezone() {
|
|
|
2450
2516
|
}
|
|
2451
2517
|
}
|
|
2452
2518
|
function detectPlatform() {
|
|
2453
|
-
return
|
|
2519
|
+
return import_react_native11.Platform.OS === "ios" ? "ios" : "android";
|
|
2454
2520
|
}
|
|
2455
|
-
var
|
|
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
|
-
|
|
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.
|
|
2631
|
-
return "2.
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
2969
|
+
import_react_native13 = require("react-native");
|
|
2904
2970
|
AUTH_STATUS2 = {
|
|
2905
2971
|
NOT_DETERMINED: -1,
|
|
2906
2972
|
DENIED: 0,
|
|
@@ -3082,10 +3148,7 @@ var init_NotificationsManager = __esm({
|
|
|
3082
3148
|
}
|
|
3083
3149
|
applyConfig(config) {
|
|
3084
3150
|
this.appKey = config.appKey;
|
|
3085
|
-
this.apiBaseUrl = resolveApiBaseUrl(
|
|
3086
|
-
apiBaseUrl: config.apiBaseUrl,
|
|
3087
|
-
environment: config.environment
|
|
3088
|
-
});
|
|
3151
|
+
this.apiBaseUrl = resolveApiBaseUrl();
|
|
3089
3152
|
this.debug = config.debug ?? false;
|
|
3090
3153
|
this.permissionManager.setDebug(this.debug);
|
|
3091
3154
|
}
|
|
@@ -3261,7 +3324,8 @@ var init_OnboardingError = __esm({
|
|
|
3261
3324
|
};
|
|
3262
3325
|
ONBOARDING_ERROR_CODES = {
|
|
3263
3326
|
NOT_INITIALIZED: "ONBOARDING_NOT_INITIALIZED",
|
|
3264
|
-
INVALID_STEP_NAME: "ONBOARDING_INVALID_STEP_NAME"
|
|
3327
|
+
INVALID_STEP_NAME: "ONBOARDING_INVALID_STEP_NAME",
|
|
3328
|
+
INVALID_ORDER: "ONBOARDING_INVALID_ORDER"
|
|
3265
3329
|
};
|
|
3266
3330
|
}
|
|
3267
3331
|
});
|
|
@@ -3291,16 +3355,20 @@ var init_OnboardingManager = __esm({
|
|
|
3291
3355
|
* Saves the step name internally for implicit drop detection on the backend.
|
|
3292
3356
|
*
|
|
3293
3357
|
* @param stepName - Unique name for this onboarding step.
|
|
3294
|
-
* @param order -
|
|
3358
|
+
* @param order - Ordem de exibição do step. Obrigatório. Aceita decimais (ex: 2.1 para variantes A/B).
|
|
3359
|
+
* Deve ser um número finito e não-negativo. O servidor faz o floor — não arredondar aqui.
|
|
3295
3360
|
*/
|
|
3296
|
-
async step(stepName, order) {
|
|
3361
|
+
async step(stepName, order, options) {
|
|
3297
3362
|
this.assertConfig();
|
|
3298
3363
|
this.validateStepName(stepName, "step");
|
|
3364
|
+
this.validateOrder(order);
|
|
3299
3365
|
this.lastStep = stepName;
|
|
3300
|
-
const stepPayload = {
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3366
|
+
const stepPayload = {
|
|
3367
|
+
step_name: stepName,
|
|
3368
|
+
order,
|
|
3369
|
+
...options?.variantKey !== void 0 ? { variant_key: options.variantKey } : {},
|
|
3370
|
+
...options?.timeOnPrevS !== void 0 ? { time_on_prev_s: options.timeOnPrevS } : {}
|
|
3371
|
+
};
|
|
3304
3372
|
const payload = {
|
|
3305
3373
|
family: "onboarding",
|
|
3306
3374
|
type: "step",
|
|
@@ -3312,33 +3380,21 @@ var init_OnboardingManager = __esm({
|
|
|
3312
3380
|
* Tracks successful completion of the onboarding flow.
|
|
3313
3381
|
* Marks the flow as finished.
|
|
3314
3382
|
*/
|
|
3315
|
-
async complete() {
|
|
3316
|
-
this.assertConfig();
|
|
3317
|
-
this.finished = true;
|
|
3318
|
-
return this.emit("onboarding", { family: "onboarding", type: "complete" }, "complete");
|
|
3319
|
-
}
|
|
3320
|
-
/**
|
|
3321
|
-
* Tracks an explicit drop (abandonment) at the given step.
|
|
3322
|
-
* Marks the flow as finished.
|
|
3323
|
-
*
|
|
3324
|
-
* @param stepName - The step name where the user dropped off.
|
|
3325
|
-
*/
|
|
3326
|
-
async drop(stepName) {
|
|
3383
|
+
async complete(options) {
|
|
3327
3384
|
this.assertConfig();
|
|
3328
|
-
this.validateStepName(stepName, "drop");
|
|
3329
3385
|
this.finished = true;
|
|
3330
3386
|
const payload = {
|
|
3331
3387
|
family: "onboarding",
|
|
3332
|
-
type: "
|
|
3333
|
-
...{
|
|
3388
|
+
type: "complete",
|
|
3389
|
+
...options?.variantKey !== void 0 ? { variant_key: options.variantKey } : {}
|
|
3334
3390
|
};
|
|
3335
|
-
return this.emit("onboarding", payload, "
|
|
3391
|
+
return this.emit("onboarding", payload, "complete");
|
|
3336
3392
|
}
|
|
3337
3393
|
/** Returns the last step name seen, or null if no step was tracked yet. */
|
|
3338
3394
|
getLastStep() {
|
|
3339
3395
|
return this.lastStep;
|
|
3340
3396
|
}
|
|
3341
|
-
/** Returns whether the flow has been marked as finished (complete
|
|
3397
|
+
/** Returns whether the flow has been marked as finished (complete). */
|
|
3342
3398
|
isFinished() {
|
|
3343
3399
|
return this.finished;
|
|
3344
3400
|
}
|
|
@@ -3370,6 +3426,14 @@ var init_OnboardingManager = __esm({
|
|
|
3370
3426
|
);
|
|
3371
3427
|
}
|
|
3372
3428
|
}
|
|
3429
|
+
validateOrder(order) {
|
|
3430
|
+
if (order === void 0 || order === null || !Number.isFinite(order) || order < 0) {
|
|
3431
|
+
throw new OnboardingError(
|
|
3432
|
+
ONBOARDING_ERROR_CODES.INVALID_ORDER,
|
|
3433
|
+
"OnboardingManager.step(): order deve ser um n\xFAmero finito e n\xE3o-negativo."
|
|
3434
|
+
);
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3373
3437
|
};
|
|
3374
3438
|
onboardingManager = new OnboardingManager();
|
|
3375
3439
|
}
|
|
@@ -3647,11 +3711,11 @@ function getLocalizedString(text) {
|
|
|
3647
3711
|
}
|
|
3648
3712
|
function detectDeviceLanguage() {
|
|
3649
3713
|
try {
|
|
3650
|
-
if (
|
|
3651
|
-
const settings =
|
|
3714
|
+
if (import_react_native14.Platform.OS === "ios") {
|
|
3715
|
+
const settings = import_react_native14.NativeModules.SettingsManager?.settings;
|
|
3652
3716
|
return settings?.AppleLocale ?? settings?.AppleLanguages?.[0] ?? "en-US";
|
|
3653
3717
|
}
|
|
3654
|
-
return
|
|
3718
|
+
return import_react_native14.NativeModules.I18nManager?.localeIdentifier ?? "en-US";
|
|
3655
3719
|
} catch {
|
|
3656
3720
|
return "en-US";
|
|
3657
3721
|
}
|
|
@@ -3673,11 +3737,11 @@ function initLocalization(options) {
|
|
|
3673
3737
|
currentLanguage = deviceLanguage;
|
|
3674
3738
|
}
|
|
3675
3739
|
}
|
|
3676
|
-
var
|
|
3740
|
+
var import_react_native14, currentLanguage, defaultLanguage, SDK_STRINGS;
|
|
3677
3741
|
var init_localization = __esm({
|
|
3678
3742
|
"src/utils/localization.ts"() {
|
|
3679
3743
|
"use strict";
|
|
3680
|
-
|
|
3744
|
+
import_react_native14 = require("react-native");
|
|
3681
3745
|
currentLanguage = "pt-BR";
|
|
3682
3746
|
defaultLanguage = "pt-BR";
|
|
3683
3747
|
SDK_STRINGS = {
|
|
@@ -3714,48 +3778,48 @@ var init_localization = __esm({
|
|
|
3714
3778
|
|
|
3715
3779
|
// src/domains/paywall/PaywallSkeleton.tsx
|
|
3716
3780
|
function SkeletonBlock({ style, color, opacity }) {
|
|
3717
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native15.Animated.View, { style: [style, { backgroundColor: color, opacity }] });
|
|
3718
3782
|
}
|
|
3719
3783
|
function PaywallSkeleton({ backgroundColor = "#FFFFFF" }) {
|
|
3720
|
-
const pulse = (0, import_react3.useRef)(new
|
|
3784
|
+
const pulse = (0, import_react3.useRef)(new import_react_native15.Animated.Value(0.4)).current;
|
|
3721
3785
|
(0, import_react3.useEffect)(() => {
|
|
3722
|
-
const loop =
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
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 })
|
|
3726
3790
|
])
|
|
3727
3791
|
);
|
|
3728
3792
|
loop.start();
|
|
3729
3793
|
return () => loop.stop();
|
|
3730
3794
|
}, [pulse]);
|
|
3731
3795
|
const placeholder = isColorDark(backgroundColor) ? "rgba(255,255,255,0.13)" : "rgba(0,0,0,0.07)";
|
|
3732
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
3733
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
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 }) }),
|
|
3734
3798
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.hero, color: placeholder, opacity: pulse }),
|
|
3735
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
3799
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native15.View, { style: styles.titleGroup, children: [
|
|
3736
3800
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.titleLine, color: placeholder, opacity: pulse }),
|
|
3737
3801
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.titleLineShort, color: placeholder, opacity: pulse })
|
|
3738
3802
|
] }),
|
|
3739
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
3803
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native15.View, { style: styles.cardsRow, children: [
|
|
3740
3804
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.card, color: placeholder, opacity: pulse }),
|
|
3741
3805
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.card, color: placeholder, opacity: pulse })
|
|
3742
3806
|
] }),
|
|
3743
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
3807
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native15.View, { style: styles.footerGroup, children: [
|
|
3744
3808
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.cta, color: placeholder, opacity: pulse }),
|
|
3745
3809
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonBlock, { style: styles.footer, color: placeholder, opacity: pulse })
|
|
3746
3810
|
] })
|
|
3747
3811
|
] });
|
|
3748
3812
|
}
|
|
3749
|
-
var import_react3,
|
|
3813
|
+
var import_react3, import_react_native15, import_jsx_runtime, RADIUS, styles;
|
|
3750
3814
|
var init_PaywallSkeleton = __esm({
|
|
3751
3815
|
"src/domains/paywall/PaywallSkeleton.tsx"() {
|
|
3752
3816
|
"use strict";
|
|
3753
3817
|
import_react3 = require("react");
|
|
3754
|
-
|
|
3818
|
+
import_react_native15 = require("react-native");
|
|
3755
3819
|
init_extractFirstPageBackground();
|
|
3756
3820
|
import_jsx_runtime = require("react/jsx-runtime");
|
|
3757
3821
|
RADIUS = 14;
|
|
3758
|
-
styles =
|
|
3822
|
+
styles = import_react_native15.StyleSheet.create({
|
|
3759
3823
|
card: { borderRadius: RADIUS, flex: 1, height: 120 },
|
|
3760
3824
|
cardsRow: { flexDirection: "row", gap: 12, marginTop: "auto", paddingHorizontal: 24 },
|
|
3761
3825
|
container: { flex: 1, paddingBottom: 40, paddingTop: 64 },
|
|
@@ -3821,7 +3885,7 @@ function getNativeWebView() {
|
|
|
3821
3885
|
if (NativeWebViewComponent) return NativeWebViewComponent;
|
|
3822
3886
|
if (nativeWebViewLookupFailed) return null;
|
|
3823
3887
|
try {
|
|
3824
|
-
NativeWebViewComponent = (0,
|
|
3888
|
+
NativeWebViewComponent = (0, import_react_native16.requireNativeComponent)("PaywalloWebView");
|
|
3825
3889
|
return NativeWebViewComponent;
|
|
3826
3890
|
} catch {
|
|
3827
3891
|
nativeWebViewLookupFailed = true;
|
|
@@ -3830,9 +3894,9 @@ function getNativeWebView() {
|
|
|
3830
3894
|
}
|
|
3831
3895
|
function getWebViewEmitter() {
|
|
3832
3896
|
if (webViewEmitter) return webViewEmitter;
|
|
3833
|
-
const mod =
|
|
3897
|
+
const mod = import_react_native16.NativeModules.PaywalloWebViewModule;
|
|
3834
3898
|
if (!mod) return null;
|
|
3835
|
-
webViewEmitter = new
|
|
3899
|
+
webViewEmitter = new import_react_native16.NativeEventEmitter(mod);
|
|
3836
3900
|
return webViewEmitter;
|
|
3837
3901
|
}
|
|
3838
3902
|
async function triggerNativeHaptic(style) {
|
|
@@ -3923,10 +3987,10 @@ function PaywallWebView({
|
|
|
3923
3987
|
}
|
|
3924
3988
|
}, []);
|
|
3925
3989
|
const injectScript = (0, import_react4.useCallback)((script) => {
|
|
3926
|
-
if (
|
|
3927
|
-
const handle = (0,
|
|
3990
|
+
if (import_react_native16.Platform.OS === "android") {
|
|
3991
|
+
const handle = (0, import_react_native16.findNodeHandle)(webViewRef.current);
|
|
3928
3992
|
if (handle == null) return;
|
|
3929
|
-
|
|
3993
|
+
import_react_native16.UIManager.dispatchViewManagerCommand(handle, "injectJavaScript", [script]);
|
|
3930
3994
|
return;
|
|
3931
3995
|
}
|
|
3932
3996
|
setScriptToInject(script);
|
|
@@ -3986,7 +4050,7 @@ function PaywallWebView({
|
|
|
3986
4050
|
if (message.payload?.url) {
|
|
3987
4051
|
const url = message.payload.url;
|
|
3988
4052
|
if (/^https?:\/\//i.test(url) || /^mailto:/i.test(url) || /^itms-apps:/i.test(url) || /^market:/i.test(url)) {
|
|
3989
|
-
void
|
|
4053
|
+
void import_react_native16.Linking.openURL(url);
|
|
3990
4054
|
}
|
|
3991
4055
|
}
|
|
3992
4056
|
break;
|
|
@@ -4067,18 +4131,18 @@ function PaywallWebView({
|
|
|
4067
4131
|
injectScript(buildPurchaseStateScript(isPurchasing));
|
|
4068
4132
|
}, [isPurchasing, injectScript]);
|
|
4069
4133
|
(0, import_react4.useEffect)(() => {
|
|
4070
|
-
if (
|
|
4134
|
+
if (import_react_native16.Platform.OS !== "android") return;
|
|
4071
4135
|
const onBackPress = () => {
|
|
4072
4136
|
if (!paywallDataSent.current) return false;
|
|
4073
4137
|
injectScript(buildBackButtonScript());
|
|
4074
4138
|
return true;
|
|
4075
4139
|
};
|
|
4076
|
-
const subscription =
|
|
4140
|
+
const subscription = import_react_native16.BackHandler.addEventListener("hardwareBackPress", onBackPress);
|
|
4077
4141
|
return () => subscription.remove();
|
|
4078
4142
|
}, [injectScript]);
|
|
4079
4143
|
if (!resolvedWebUrl || !NativeWebView) return null;
|
|
4080
4144
|
const paywallUrl = `${resolvedWebUrl}/paywall/${paywallId}`;
|
|
4081
|
-
return /* @__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)(
|
|
4082
4146
|
NativeWebView,
|
|
4083
4147
|
{
|
|
4084
4148
|
ref: webViewRef,
|
|
@@ -4091,12 +4155,12 @@ function PaywallWebView({
|
|
|
4091
4155
|
}
|
|
4092
4156
|
) });
|
|
4093
4157
|
}
|
|
4094
|
-
var import_react4,
|
|
4158
|
+
var import_react4, import_react_native16, import_jsx_runtime2, NativeWebViewComponent, nativeWebViewLookupFailed, webViewEmitter, styles2;
|
|
4095
4159
|
var init_PaywallWebView = __esm({
|
|
4096
4160
|
"src/domains/paywall/PaywallWebView.tsx"() {
|
|
4097
4161
|
"use strict";
|
|
4098
4162
|
import_react4 = require("react");
|
|
4099
|
-
|
|
4163
|
+
import_react_native16 = require("react-native");
|
|
4100
4164
|
init_PaywalloClient();
|
|
4101
4165
|
init_parseWebViewMessage();
|
|
4102
4166
|
init_paywallScripts();
|
|
@@ -4104,7 +4168,7 @@ var init_PaywallWebView = __esm({
|
|
|
4104
4168
|
NativeWebViewComponent = null;
|
|
4105
4169
|
nativeWebViewLookupFailed = false;
|
|
4106
4170
|
webViewEmitter = null;
|
|
4107
|
-
styles2 =
|
|
4171
|
+
styles2 = import_react_native16.StyleSheet.create({
|
|
4108
4172
|
container: { flex: 1 },
|
|
4109
4173
|
webview: { flex: 1, backgroundColor: "transparent" }
|
|
4110
4174
|
});
|
|
@@ -4239,7 +4303,7 @@ function mapNativePurchase(native) {
|
|
|
4239
4303
|
transactionId: native.transactionId,
|
|
4240
4304
|
transactionDate: native.transactionDate,
|
|
4241
4305
|
receipt: native.receipt,
|
|
4242
|
-
platform:
|
|
4306
|
+
platform: import_react_native17.Platform.OS
|
|
4243
4307
|
};
|
|
4244
4308
|
}
|
|
4245
4309
|
function normalizeTransactionUpdate(raw) {
|
|
@@ -4259,17 +4323,17 @@ function normalizeTransactionUpdate(raw) {
|
|
|
4259
4323
|
if (typeof r.currency === "string") update.currency = r.currency;
|
|
4260
4324
|
return update;
|
|
4261
4325
|
}
|
|
4262
|
-
var
|
|
4326
|
+
var import_react_native17, TRANSACTION_UPDATE_EVENT, PaywalloStoreKitNative, nativeStoreKit, NativeStoreKit;
|
|
4263
4327
|
var init_NativeStoreKit = __esm({
|
|
4264
4328
|
"src/domains/iap/NativeStoreKit.ts"() {
|
|
4265
4329
|
"use strict";
|
|
4266
|
-
|
|
4330
|
+
import_react_native17 = require("react-native");
|
|
4267
4331
|
init_PaywalloClient();
|
|
4268
4332
|
init_uuid();
|
|
4269
4333
|
init_IdentityManager();
|
|
4270
4334
|
init_PurchaseError();
|
|
4271
4335
|
TRANSACTION_UPDATE_EVENT = "PaywalloTransactionUpdate";
|
|
4272
|
-
PaywalloStoreKitNative =
|
|
4336
|
+
PaywalloStoreKitNative = import_react_native17.NativeModules.PaywalloStoreKit ?? null;
|
|
4273
4337
|
nativeStoreKit = {
|
|
4274
4338
|
isAvailable: isAvailable3,
|
|
4275
4339
|
async getProducts(productIds) {
|
|
@@ -4338,7 +4402,7 @@ var init_NativeStoreKit = __esm({
|
|
|
4338
4402
|
subscribeToTransactionUpdates(listener) {
|
|
4339
4403
|
if (!PaywalloStoreKitNative) return null;
|
|
4340
4404
|
try {
|
|
4341
|
-
const EmitterCtor =
|
|
4405
|
+
const EmitterCtor = import_react_native17.NativeEventEmitter;
|
|
4342
4406
|
const emitter = new EmitterCtor(PaywalloStoreKitNative);
|
|
4343
4407
|
const sub = emitter.addListener(TRANSACTION_UPDATE_EVENT, (payload) => {
|
|
4344
4408
|
const update = normalizeTransactionUpdate(payload);
|
|
@@ -4971,11 +5035,11 @@ var init_types2 = __esm({
|
|
|
4971
5035
|
});
|
|
4972
5036
|
|
|
4973
5037
|
// src/core/network/NetworkMonitor.ts
|
|
4974
|
-
var
|
|
5038
|
+
var import_react_native18, NetworkMonitorClass, networkMonitor;
|
|
4975
5039
|
var init_NetworkMonitor = __esm({
|
|
4976
5040
|
"src/core/network/NetworkMonitor.ts"() {
|
|
4977
5041
|
"use strict";
|
|
4978
|
-
|
|
5042
|
+
import_react_native18 = require("react-native");
|
|
4979
5043
|
init_types2();
|
|
4980
5044
|
NetworkMonitorClass = class {
|
|
4981
5045
|
constructor() {
|
|
@@ -5004,7 +5068,7 @@ var init_NetworkMonitor = __esm({
|
|
|
5004
5068
|
}, this.config.checkInterval);
|
|
5005
5069
|
}
|
|
5006
5070
|
setupAppStateListener() {
|
|
5007
|
-
this.appStateSubscription =
|
|
5071
|
+
this.appStateSubscription = import_react_native18.AppState.addEventListener("change", (state) => {
|
|
5008
5072
|
if (state === "active") {
|
|
5009
5073
|
if (!this.checkIntervalId) {
|
|
5010
5074
|
this.checkIntervalId = setInterval(() => {
|
|
@@ -5226,7 +5290,7 @@ var init_QueueProcessor = __esm({
|
|
|
5226
5290
|
for (const item of batch) {
|
|
5227
5291
|
retryIds.add(item.id);
|
|
5228
5292
|
}
|
|
5229
|
-
console.
|
|
5293
|
+
if (this.config.debug) console.log("[Paywallo:QUEUE] event batch network error \u2014 items will retry", { size: batch.length, error: error instanceof Error ? error.message : String(error) });
|
|
5230
5294
|
this.log("Event batch threw network error - will retry", {
|
|
5231
5295
|
size: batch.length,
|
|
5232
5296
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -5239,7 +5303,7 @@ var init_QueueProcessor = __esm({
|
|
|
5239
5303
|
processed++;
|
|
5240
5304
|
}
|
|
5241
5305
|
this.log("Event batch processed successfully", { size: batch.length });
|
|
5242
|
-
} else if (response.status >= 400 && response.status < 500) {
|
|
5306
|
+
} else if (response.status >= 400 && response.status < 500 && response.status !== 429) {
|
|
5243
5307
|
for (const item of batch) {
|
|
5244
5308
|
await offlineQueue.removeItem(item.id);
|
|
5245
5309
|
failed++;
|
|
@@ -5251,7 +5315,7 @@ var init_QueueProcessor = __esm({
|
|
|
5251
5315
|
console.log("[Paywallo:QUEUE] event batch deduplicated by server \u2014 items dropped (benign)", { status: response.status, size: batch.length, error: responseError });
|
|
5252
5316
|
}
|
|
5253
5317
|
} else {
|
|
5254
|
-
console.
|
|
5318
|
+
if (this.config.debug) console.log("[Paywallo:QUEUE] event batch failed PERMANENTLY (4xx) \u2014 items dropped", { status: response.status, size: batch.length, responseBody: typeof response.data === "string" ? response.data.slice(0, 1e3) : JSON.stringify(response.data).slice(0, 1e3), firstItemBody: typeof batch[0].body === "string" ? batch[0].body.slice(0, 1e3) : JSON.stringify(batch[0].body).slice(0, 1e3) });
|
|
5255
5319
|
}
|
|
5256
5320
|
this.log("Event batch failed permanently (4xx) - removing from queue", {
|
|
5257
5321
|
status: response.status,
|
|
@@ -5262,7 +5326,7 @@ var init_QueueProcessor = __esm({
|
|
|
5262
5326
|
for (const item of batch) {
|
|
5263
5327
|
retryIds.add(item.id);
|
|
5264
5328
|
}
|
|
5265
|
-
console.
|
|
5329
|
+
if (this.config.debug) console.log("[Paywallo:QUEUE] event batch server error (5xx) \u2014 will retry", { status: response.status, size: batch.length });
|
|
5266
5330
|
this.log("Event batch failed with server error - will retry", {
|
|
5267
5331
|
status: response.status,
|
|
5268
5332
|
size: batch.length
|
|
@@ -5292,7 +5356,7 @@ var init_QueueProcessor = __esm({
|
|
|
5292
5356
|
skipRetry: false
|
|
5293
5357
|
});
|
|
5294
5358
|
} catch (error) {
|
|
5295
|
-
console.
|
|
5359
|
+
if (this.config.debug) console.log("[Paywallo:QUEUE] individual item network error \u2014 will retry", { id: item.id, url: item.url, error: error instanceof Error ? error.message : String(error) });
|
|
5296
5360
|
this.log("Request threw network error - will retry", {
|
|
5297
5361
|
id: item.id,
|
|
5298
5362
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -5303,7 +5367,7 @@ var init_QueueProcessor = __esm({
|
|
|
5303
5367
|
this.log("Queue item processed successfully", { id: item.id });
|
|
5304
5368
|
return { success: true, permanent: false };
|
|
5305
5369
|
}
|
|
5306
|
-
if (response.status >= 400 && response.status < 500) {
|
|
5370
|
+
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
|
|
5307
5371
|
this.log("Request failed with permanent client error - removing from queue", {
|
|
5308
5372
|
id: item.id,
|
|
5309
5373
|
url: item.url,
|
|
@@ -5373,11 +5437,11 @@ var init_queue = __esm({
|
|
|
5373
5437
|
});
|
|
5374
5438
|
|
|
5375
5439
|
// src/domains/iap/IAPValidator.ts
|
|
5376
|
-
var
|
|
5440
|
+
var import_react_native19, IAPValidator;
|
|
5377
5441
|
var init_IAPValidator = __esm({
|
|
5378
5442
|
"src/domains/iap/IAPValidator.ts"() {
|
|
5379
5443
|
"use strict";
|
|
5380
|
-
|
|
5444
|
+
import_react_native19 = require("react-native");
|
|
5381
5445
|
init_PaywalloClient();
|
|
5382
5446
|
init_queue();
|
|
5383
5447
|
init_PurchaseError();
|
|
@@ -5403,7 +5467,7 @@ var init_IAPValidator = __esm({
|
|
|
5403
5467
|
async validateWithServer(purchase, productId, options) {
|
|
5404
5468
|
const apiClient = this.getApiClientFn();
|
|
5405
5469
|
const product = this.getProductFromCache(productId);
|
|
5406
|
-
const platform =
|
|
5470
|
+
const platform = import_react_native19.Platform.OS;
|
|
5407
5471
|
const distinctId = PaywalloClient.getDistinctId();
|
|
5408
5472
|
return this.validateWithRetry(
|
|
5409
5473
|
() => apiClient.validatePurchase(
|
|
@@ -5438,7 +5502,7 @@ var init_IAPValidator = __esm({
|
|
|
5438
5502
|
try {
|
|
5439
5503
|
const apiClient = this.getApiClientFn();
|
|
5440
5504
|
const product = this.getProductFromCache(productId);
|
|
5441
|
-
const platform =
|
|
5505
|
+
const platform = import_react_native19.Platform.OS;
|
|
5442
5506
|
const distinctId = PaywalloClient.getDistinctId();
|
|
5443
5507
|
const appKey = apiClient.getAppKey();
|
|
5444
5508
|
const body = {
|
|
@@ -5478,11 +5542,11 @@ function getIAPService() {
|
|
|
5478
5542
|
}
|
|
5479
5543
|
return _instance;
|
|
5480
5544
|
}
|
|
5481
|
-
var
|
|
5545
|
+
var import_react_native20, IAPService, _instance;
|
|
5482
5546
|
var init_IAPService = __esm({
|
|
5483
5547
|
"src/domains/iap/IAPService.ts"() {
|
|
5484
5548
|
"use strict";
|
|
5485
|
-
|
|
5549
|
+
import_react_native20 = require("react-native");
|
|
5486
5550
|
init_PaywalloClient();
|
|
5487
5551
|
init_IAPTransactionEmitter();
|
|
5488
5552
|
init_IAPValidator();
|
|
@@ -5632,7 +5696,7 @@ var init_IAPService = __esm({
|
|
|
5632
5696
|
const transactions = await nativeStoreKit.getActiveTransactions();
|
|
5633
5697
|
const apiClient = this.getApiClient();
|
|
5634
5698
|
const distinctId = PaywalloClient.getDistinctId();
|
|
5635
|
-
const platform =
|
|
5699
|
+
const platform = import_react_native20.Platform.OS;
|
|
5636
5700
|
const results = await Promise.allSettled(
|
|
5637
5701
|
transactions.map((tx) => {
|
|
5638
5702
|
const product = this.productsCache.get(tx.productId);
|
|
@@ -5727,7 +5791,7 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
|
|
|
5727
5791
|
const [isPurchasing, setIsPurchasing] = (0, import_react6.useState)(false);
|
|
5728
5792
|
const isPurchasingRef = (0, import_react6.useRef)(false);
|
|
5729
5793
|
const [isClosing, setIsClosing] = (0, import_react6.useState)(false);
|
|
5730
|
-
const slideAnim = (0, import_react6.useRef)(new
|
|
5794
|
+
const slideAnim = (0, import_react6.useRef)(new import_react_native21.Animated.Value(0)).current;
|
|
5731
5795
|
const presentedAtRef = (0, import_react6.useRef)(Date.now());
|
|
5732
5796
|
const closedRef = (0, import_react6.useRef)(false);
|
|
5733
5797
|
const { trackDismissed, trackProductSelected, trackPurchased } = usePaywallTracking();
|
|
@@ -5735,8 +5799,8 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
|
|
|
5735
5799
|
if (closedRef.current) return;
|
|
5736
5800
|
closedRef.current = true;
|
|
5737
5801
|
const animTarget = openAnim ?? slideAnim;
|
|
5738
|
-
|
|
5739
|
-
toValue:
|
|
5802
|
+
import_react_native21.Animated.timing(animTarget, {
|
|
5803
|
+
toValue: import_react_native21.Dimensions.get("window").height,
|
|
5740
5804
|
duration: 350,
|
|
5741
5805
|
useNativeDriver: true
|
|
5742
5806
|
}).start(() => {
|
|
@@ -5756,7 +5820,7 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
|
|
|
5756
5820
|
closeWithReason("dismissed");
|
|
5757
5821
|
}, [isClosing, closeWithReason]);
|
|
5758
5822
|
(0, import_react6.useEffect)(() => {
|
|
5759
|
-
const sub =
|
|
5823
|
+
const sub = import_react_native21.AppState.addEventListener("change", (nextState) => {
|
|
5760
5824
|
if (isPurchasingRef.current) return;
|
|
5761
5825
|
if (nextState === "background" || nextState === "inactive") {
|
|
5762
5826
|
closeWithReason("backgrounded");
|
|
@@ -5824,12 +5888,12 @@ function usePaywallActions(placement, paywallConfig, onResult, variantKey, campa
|
|
|
5824
5888
|
}, [isPurchasing, onResult, paywallConfig, placement, trackDismissed, variantKey, campaignId, variantId]);
|
|
5825
5889
|
return { isPurchasing, slideAnim, handleClose, handlePurchase, handleRestore };
|
|
5826
5890
|
}
|
|
5827
|
-
var import_react6,
|
|
5891
|
+
var import_react6, import_react_native21, PAYWALL_TIMEOUT_MS;
|
|
5828
5892
|
var init_usePaywallActions = __esm({
|
|
5829
5893
|
"src/domains/paywall/usePaywallActions.ts"() {
|
|
5830
5894
|
"use strict";
|
|
5831
5895
|
import_react6 = require("react");
|
|
5832
|
-
|
|
5896
|
+
import_react_native21 = require("react-native");
|
|
5833
5897
|
init_IAPService();
|
|
5834
5898
|
init_usePaywallTracking();
|
|
5835
5899
|
PAYWALL_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
@@ -5950,11 +6014,11 @@ function ErrorFallback({ description, onRetry, onClose }) {
|
|
|
5950
6014
|
const title = overrides?.title ?? getSdkString("paywallErrorTitle");
|
|
5951
6015
|
const retryLabel = overrides?.retry ?? getSdkString("paywallRetryButton");
|
|
5952
6016
|
const closeLabel = overrides?.close ?? getSdkString("paywallCloseButton");
|
|
5953
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
5954
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
5955
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
5956
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
5957
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
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 }) })
|
|
5958
6022
|
] }) });
|
|
5959
6023
|
}
|
|
5960
6024
|
function PaywallModal({
|
|
@@ -5976,8 +6040,8 @@ function PaywallModal({
|
|
|
5976
6040
|
campaignId,
|
|
5977
6041
|
variantId
|
|
5978
6042
|
);
|
|
5979
|
-
const screenHeight =
|
|
5980
|
-
const openAnim = (0, import_react8.useRef)(new
|
|
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;
|
|
5981
6045
|
const [modalVisible, setModalVisible] = (0, import_react8.useState)(false);
|
|
5982
6046
|
const handleResult = (0, import_react8.useCallback)((result) => {
|
|
5983
6047
|
setModalVisible(false);
|
|
@@ -5987,7 +6051,7 @@ function PaywallModal({
|
|
|
5987
6051
|
const [webViewError, setWebViewError] = (0, import_react8.useState)(null);
|
|
5988
6052
|
const [retryCount, setRetryCount] = (0, import_react8.useState)(0);
|
|
5989
6053
|
const [showSkeleton, setShowSkeleton] = (0, import_react8.useState)(true);
|
|
5990
|
-
const skeletonOpacity = (0, import_react8.useRef)(new
|
|
6054
|
+
const skeletonOpacity = (0, import_react8.useRef)(new import_react_native22.Animated.Value(1)).current;
|
|
5991
6055
|
const retryCountRef = (0, import_react8.useRef)(0);
|
|
5992
6056
|
const handleWebViewError = (0, import_react8.useCallback)(
|
|
5993
6057
|
(err) => {
|
|
@@ -6008,10 +6072,10 @@ function PaywallModal({
|
|
|
6008
6072
|
skeletonOpacity.setValue(1);
|
|
6009
6073
|
}, [skeletonOpacity]);
|
|
6010
6074
|
const handleWebViewReady = (0, import_react8.useCallback)(() => {
|
|
6011
|
-
|
|
6075
|
+
import_react_native22.Animated.timing(skeletonOpacity, {
|
|
6012
6076
|
toValue: 0,
|
|
6013
6077
|
duration: 250,
|
|
6014
|
-
easing:
|
|
6078
|
+
easing: import_react_native22.Easing.out(import_react_native22.Easing.cubic),
|
|
6015
6079
|
useNativeDriver: true
|
|
6016
6080
|
}).start(() => setShowSkeleton(false));
|
|
6017
6081
|
}, [skeletonOpacity]);
|
|
@@ -6025,11 +6089,11 @@ function PaywallModal({
|
|
|
6025
6089
|
setModalVisible(true);
|
|
6026
6090
|
setShowSkeleton(true);
|
|
6027
6091
|
skeletonOpacity.setValue(1);
|
|
6028
|
-
openAnim.setValue(
|
|
6029
|
-
|
|
6092
|
+
openAnim.setValue(import_react_native22.Dimensions.get("window").height);
|
|
6093
|
+
import_react_native22.Animated.timing(openAnim, {
|
|
6030
6094
|
toValue: 0,
|
|
6031
6095
|
duration: 550,
|
|
6032
|
-
easing:
|
|
6096
|
+
easing: import_react_native22.Easing.out(import_react_native22.Easing.cubic),
|
|
6033
6097
|
useNativeDriver: true
|
|
6034
6098
|
}).start();
|
|
6035
6099
|
}
|
|
@@ -6037,7 +6101,7 @@ function PaywallModal({
|
|
|
6037
6101
|
if (!modalVisible && !visible) return null;
|
|
6038
6102
|
const skeletonBackground = paywallConfig && "craftData" in paywallConfig.config ? extractFirstPageBackground(paywallConfig.config.craftData) : "#FFFFFF";
|
|
6039
6103
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
6040
|
-
|
|
6104
|
+
import_react_native22.Modal,
|
|
6041
6105
|
{
|
|
6042
6106
|
visible: modalVisible,
|
|
6043
6107
|
animationType: "none",
|
|
@@ -6045,8 +6109,8 @@ function PaywallModal({
|
|
|
6045
6109
|
onRequestClose: handleClose,
|
|
6046
6110
|
transparent: true,
|
|
6047
6111
|
statusBarTranslucent: true,
|
|
6048
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
6049
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
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 }) }),
|
|
6050
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)(
|
|
6051
6115
|
ErrorFallback,
|
|
6052
6116
|
{
|
|
@@ -6073,9 +6137,9 @@ function PaywallModal({
|
|
|
6073
6137
|
retryCount
|
|
6074
6138
|
) }),
|
|
6075
6139
|
showSkeleton && !error && !webViewError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
6076
|
-
|
|
6140
|
+
import_react_native22.Animated.View,
|
|
6077
6141
|
{
|
|
6078
|
-
style: [
|
|
6142
|
+
style: [import_react_native22.StyleSheet.absoluteFill, { opacity: skeletonOpacity }],
|
|
6079
6143
|
pointerEvents: "none",
|
|
6080
6144
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaywallSkeleton, { backgroundColor: skeletonBackground })
|
|
6081
6145
|
}
|
|
@@ -6084,12 +6148,12 @@ function PaywallModal({
|
|
|
6084
6148
|
}
|
|
6085
6149
|
);
|
|
6086
6150
|
}
|
|
6087
|
-
var import_react8,
|
|
6151
|
+
var import_react8, import_react_native22, import_jsx_runtime3, styles3;
|
|
6088
6152
|
var init_PaywallModal = __esm({
|
|
6089
6153
|
"src/domains/paywall/PaywallModal.tsx"() {
|
|
6090
6154
|
"use strict";
|
|
6091
6155
|
import_react8 = require("react");
|
|
6092
|
-
|
|
6156
|
+
import_react_native22 = require("react-native");
|
|
6093
6157
|
init_PaywalloClient();
|
|
6094
6158
|
init_localization();
|
|
6095
6159
|
init_extractFirstPageBackground();
|
|
@@ -6098,7 +6162,7 @@ var init_PaywallModal = __esm({
|
|
|
6098
6162
|
init_usePaywallActions();
|
|
6099
6163
|
init_usePaywallLoader();
|
|
6100
6164
|
import_jsx_runtime3 = require("react/jsx-runtime");
|
|
6101
|
-
styles3 =
|
|
6165
|
+
styles3 = import_react_native22.StyleSheet.create({
|
|
6102
6166
|
overlay: { flex: 1, backgroundColor: "rgba(0,0,0,0.3)" },
|
|
6103
6167
|
animatedContainer: { flex: 1, backgroundColor: "#fff" },
|
|
6104
6168
|
container: { flex: 1, backgroundColor: "#fff" },
|
|
@@ -6268,7 +6332,7 @@ function getNativeWebView2() {
|
|
|
6268
6332
|
if (NativeWebViewComponent2) return NativeWebViewComponent2;
|
|
6269
6333
|
if (nativeLookupFailed) return null;
|
|
6270
6334
|
try {
|
|
6271
|
-
NativeWebViewComponent2 = (0,
|
|
6335
|
+
NativeWebViewComponent2 = (0, import_react_native23.requireNativeComponent)("PaywalloWebView");
|
|
6272
6336
|
return NativeWebViewComponent2;
|
|
6273
6337
|
} catch {
|
|
6274
6338
|
nativeLookupFailed = true;
|
|
@@ -6291,20 +6355,20 @@ function PaywallWebViewPrewarmer({
|
|
|
6291
6355
|
if (PaywalloClient.getConfig()?.debug) {
|
|
6292
6356
|
console.log(`[Paywallo PREWARM] mounting hidden WebView: ${preheatUrl}`);
|
|
6293
6357
|
}
|
|
6294
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
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 }) });
|
|
6295
6359
|
}
|
|
6296
|
-
var import_react9,
|
|
6360
|
+
var import_react9, import_react_native23, import_jsx_runtime4, NativeWebViewComponent2, nativeLookupFailed, DEFAULT_DURATION_MS, styles4;
|
|
6297
6361
|
var init_PaywallWebViewPrewarmer = __esm({
|
|
6298
6362
|
"src/domains/paywall/PaywallWebViewPrewarmer.tsx"() {
|
|
6299
6363
|
"use strict";
|
|
6300
6364
|
import_react9 = require("react");
|
|
6301
|
-
|
|
6365
|
+
import_react_native23 = require("react-native");
|
|
6302
6366
|
init_PaywalloClient();
|
|
6303
6367
|
import_jsx_runtime4 = require("react/jsx-runtime");
|
|
6304
6368
|
NativeWebViewComponent2 = null;
|
|
6305
6369
|
nativeLookupFailed = false;
|
|
6306
6370
|
DEFAULT_DURATION_MS = 60 * 1e3;
|
|
6307
|
-
styles4 =
|
|
6371
|
+
styles4 = import_react_native23.StyleSheet.create({
|
|
6308
6372
|
hidden: {
|
|
6309
6373
|
height: 1,
|
|
6310
6374
|
left: -9999,
|
|
@@ -6821,8 +6885,9 @@ var init_schemas = __esm({
|
|
|
6821
6885
|
path: ["transaction_id"]
|
|
6822
6886
|
});
|
|
6823
6887
|
onboardingEventSchema = import_zod.z.object({
|
|
6824
|
-
type: import_zod.z.enum(["step", "complete"
|
|
6825
|
-
|
|
6888
|
+
type: import_zod.z.enum(["step", "complete"]),
|
|
6889
|
+
family: import_zod.z.literal("onboarding").optional(),
|
|
6890
|
+
order: import_zod.z.number().nonnegative().optional(),
|
|
6826
6891
|
step_name: import_zod.z.string().optional(),
|
|
6827
6892
|
variant_key: import_zod.z.string().optional(),
|
|
6828
6893
|
time_on_prev_s: import_zod.z.number().nonnegative().optional()
|
|
@@ -6919,7 +6984,7 @@ function isValidEventName(name) {
|
|
|
6919
6984
|
async function trackEvent(apiClient, state, eventName, options) {
|
|
6920
6985
|
const distinctId = identityManager.getDistinctId();
|
|
6921
6986
|
if (!distinctId) {
|
|
6922
|
-
console.
|
|
6987
|
+
if (state.config?.debug) console.log("[Paywallo:DROP] event dropped \u2014 no distinctId available yet", { eventName });
|
|
6923
6988
|
return;
|
|
6924
6989
|
}
|
|
6925
6990
|
if (!isValidEventName(eventName)) {
|
|
@@ -7341,12 +7406,12 @@ async function detectEnvironment() {
|
|
|
7341
7406
|
cached = "sandbox";
|
|
7342
7407
|
return cached;
|
|
7343
7408
|
}
|
|
7344
|
-
if (!
|
|
7409
|
+
if (!nativeModule2) {
|
|
7345
7410
|
cached = "production";
|
|
7346
7411
|
return cached;
|
|
7347
7412
|
}
|
|
7348
7413
|
try {
|
|
7349
|
-
const result = await
|
|
7414
|
+
const result = await nativeModule2.detect();
|
|
7350
7415
|
cached = result === "sandbox" ? "sandbox" : "production";
|
|
7351
7416
|
return cached;
|
|
7352
7417
|
} catch {
|
|
@@ -7354,12 +7419,12 @@ async function detectEnvironment() {
|
|
|
7354
7419
|
return cached;
|
|
7355
7420
|
}
|
|
7356
7421
|
}
|
|
7357
|
-
var
|
|
7422
|
+
var import_react_native24, nativeModule2, cached;
|
|
7358
7423
|
var init_detectEnvironment = __esm({
|
|
7359
7424
|
"src/utils/detectEnvironment.ts"() {
|
|
7360
7425
|
"use strict";
|
|
7361
|
-
|
|
7362
|
-
|
|
7426
|
+
import_react_native24 = require("react-native");
|
|
7427
|
+
nativeModule2 = import_react_native24.NativeModules.PaywalloEnv ?? null;
|
|
7363
7428
|
cached = null;
|
|
7364
7429
|
}
|
|
7365
7430
|
});
|
|
@@ -7427,6 +7492,32 @@ var init_apiPurchaseMethods = __esm({
|
|
|
7427
7492
|
}
|
|
7428
7493
|
});
|
|
7429
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
|
+
|
|
7430
7521
|
// src/core/ApiCache.ts
|
|
7431
7522
|
var ApiCache;
|
|
7432
7523
|
var init_ApiCache = __esm({
|
|
@@ -7654,6 +7745,11 @@ function isServerError(res) {
|
|
|
7654
7745
|
const r = res;
|
|
7655
7746
|
return r.ok === false && typeof r.status === "number" && r.status >= 500;
|
|
7656
7747
|
}
|
|
7748
|
+
function isRateLimitError(res) {
|
|
7749
|
+
if (typeof res !== "object" || res === null) return false;
|
|
7750
|
+
const r = res;
|
|
7751
|
+
return r.ok === false && r.status === 429;
|
|
7752
|
+
}
|
|
7657
7753
|
async function postWithQueue(deps, url, payload, label, priority) {
|
|
7658
7754
|
const enqueue = async () => {
|
|
7659
7755
|
await offlineQueue.enqueue(
|
|
@@ -7665,6 +7761,11 @@ async function postWithQueue(deps, url, payload, label, priority) {
|
|
|
7665
7761
|
priority
|
|
7666
7762
|
);
|
|
7667
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
|
+
}
|
|
7668
7769
|
if (deps.isOfflineQueueEnabled() && !networkMonitor.isOnline()) {
|
|
7669
7770
|
await enqueue();
|
|
7670
7771
|
if (deps.isDebug()) console.log("[Paywallo:ApiClient] Queued for offline:", label, priority ?? "normal");
|
|
@@ -7675,6 +7776,9 @@ async function postWithQueue(deps, url, payload, label, priority) {
|
|
|
7675
7776
|
if (isServerError(res) && deps.isOfflineQueueEnabled()) {
|
|
7676
7777
|
if (deps.isDebug()) console.log("[Paywallo:ApiClient] Server error, queued for retry:", label, priority ?? "normal");
|
|
7677
7778
|
await enqueue();
|
|
7779
|
+
} else if (isRateLimitError(res) && deps.isOfflineQueueEnabled()) {
|
|
7780
|
+
if (deps.isDebug()) console.log("[Paywallo:ApiClient] Rate limited (429), queued for retry:", label, priority ?? "normal");
|
|
7781
|
+
await enqueue();
|
|
7678
7782
|
}
|
|
7679
7783
|
} catch (error) {
|
|
7680
7784
|
if (deps.isDebug()) console.log("[Paywallo:ApiClient] Request failed:", label, error);
|
|
@@ -7719,7 +7823,7 @@ function buildV2Envelope(events, providerContext) {
|
|
|
7719
7823
|
return { id, ts: event.timestamp, name: family, payload };
|
|
7720
7824
|
});
|
|
7721
7825
|
if (context.sdk_version === void 0) context.sdk_version = SDK_VERSION;
|
|
7722
|
-
if (context.platform === void 0) context.platform =
|
|
7826
|
+
if (context.platform === void 0) context.platform = import_react_native26.Platform.OS;
|
|
7723
7827
|
if (context.distinct_id === void 0 && events.length > 0) {
|
|
7724
7828
|
context.distinct_id = events[0].distinctId;
|
|
7725
7829
|
}
|
|
@@ -7777,11 +7881,11 @@ function splitPayloadAndContext(properties) {
|
|
|
7777
7881
|
}
|
|
7778
7882
|
return { payload, promoted };
|
|
7779
7883
|
}
|
|
7780
|
-
var
|
|
7884
|
+
var import_react_native26, import_zod2, v2EventSchema, v2ContextSchema, v2EnvelopeSchema, IDS_PROMO_ALIASES, CONTEXT_KEY_ALIASES;
|
|
7781
7885
|
var init_eventEnvelopeV2 = __esm({
|
|
7782
7886
|
"src/core/eventEnvelopeV2.ts"() {
|
|
7783
7887
|
"use strict";
|
|
7784
|
-
|
|
7888
|
+
import_react_native26 = require("react-native");
|
|
7785
7889
|
import_zod2 = require("zod");
|
|
7786
7890
|
init_uuid();
|
|
7787
7891
|
init_eventFamilies();
|
|
@@ -7859,11 +7963,11 @@ var init_events = __esm({
|
|
|
7859
7963
|
});
|
|
7860
7964
|
|
|
7861
7965
|
// src/core/EventBatcher.ts
|
|
7862
|
-
var
|
|
7966
|
+
var import_react_native27, BATCH_MAX_SIZE, BATCH_FLUSH_MS, EVENT_NAME_REGEX, V2_BATCH_ENDPOINT, EventBatcher;
|
|
7863
7967
|
var init_EventBatcher = __esm({
|
|
7864
7968
|
"src/core/EventBatcher.ts"() {
|
|
7865
7969
|
"use strict";
|
|
7866
|
-
|
|
7970
|
+
import_react_native27 = require("react-native");
|
|
7867
7971
|
init_eventEnvelopeV2();
|
|
7868
7972
|
init_events();
|
|
7869
7973
|
BATCH_MAX_SIZE = 25;
|
|
@@ -7872,10 +7976,8 @@ var init_EventBatcher = __esm({
|
|
|
7872
7976
|
V2_BATCH_ENDPOINT = "/sdk/ingest/batch";
|
|
7873
7977
|
EventBatcher = class {
|
|
7874
7978
|
constructor(post, debug = false, contextProvider = null) {
|
|
7875
|
-
this.criticalQueue = [];
|
|
7876
7979
|
this.normalQueue = [];
|
|
7877
7980
|
this.normalTimer = null;
|
|
7878
|
-
this.criticalScheduled = false;
|
|
7879
7981
|
this.post = post;
|
|
7880
7982
|
this.debug = debug;
|
|
7881
7983
|
this.contextProvider = contextProvider;
|
|
@@ -7912,14 +8014,17 @@ var init_EventBatcher = __esm({
|
|
|
7912
8014
|
const event = {
|
|
7913
8015
|
eventName,
|
|
7914
8016
|
distinctId,
|
|
7915
|
-
properties: { ...properties, platform:
|
|
8017
|
+
properties: { ...properties, platform: import_react_native27.Platform.OS },
|
|
7916
8018
|
timestamp: timestamp ?? Date.now(),
|
|
7917
8019
|
environment: environment.toLowerCase()
|
|
7918
8020
|
};
|
|
7919
8021
|
const priority = options?.priority ?? "normal";
|
|
7920
8022
|
if (priority === "critical") {
|
|
7921
|
-
|
|
7922
|
-
|
|
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
|
+
}
|
|
7923
8028
|
return;
|
|
7924
8029
|
}
|
|
7925
8030
|
this.normalQueue.push(event);
|
|
@@ -7940,9 +8045,10 @@ var init_EventBatcher = __esm({
|
|
|
7940
8045
|
}
|
|
7941
8046
|
/**
|
|
7942
8047
|
* Force flush of the normal queue. Critical events are never held in the
|
|
7943
|
-
* normal queue, so this does not affect them
|
|
7944
|
-
*
|
|
7945
|
-
* phase 2.4) can drain pending events
|
|
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.
|
|
7946
8052
|
*/
|
|
7947
8053
|
async flush() {
|
|
7948
8054
|
await this.flushNormal();
|
|
@@ -7952,28 +8058,7 @@ var init_EventBatcher = __esm({
|
|
|
7952
8058
|
clearTimeout(this.normalTimer);
|
|
7953
8059
|
this.normalTimer = null;
|
|
7954
8060
|
}
|
|
7955
|
-
this.criticalQueue = [];
|
|
7956
8061
|
this.normalQueue = [];
|
|
7957
|
-
this.criticalScheduled = false;
|
|
7958
|
-
}
|
|
7959
|
-
scheduleCriticalFlush() {
|
|
7960
|
-
if (this.criticalScheduled) return;
|
|
7961
|
-
this.criticalScheduled = true;
|
|
7962
|
-
queueMicrotask(() => {
|
|
7963
|
-
this.criticalScheduled = false;
|
|
7964
|
-
void this.flushCritical();
|
|
7965
|
-
});
|
|
7966
|
-
}
|
|
7967
|
-
async flushCritical() {
|
|
7968
|
-
if (this.criticalQueue.length === 0) return;
|
|
7969
|
-
const drained = this.criticalQueue.splice(0, this.criticalQueue.length);
|
|
7970
|
-
for (const event of drained) {
|
|
7971
|
-
try {
|
|
7972
|
-
await this.postBatch([event], `event_critical:${event.eventName}`, "critical");
|
|
7973
|
-
} catch (err) {
|
|
7974
|
-
console.error("[Paywallo:CRITICAL] critical event post failed", { eventName: event.eventName, error: err instanceof Error ? err.message : String(err) });
|
|
7975
|
-
}
|
|
7976
|
-
}
|
|
7977
8062
|
}
|
|
7978
8063
|
async flushNormal() {
|
|
7979
8064
|
if (this.normalQueue.length === 0) return;
|
|
@@ -7985,7 +8070,7 @@ var init_EventBatcher = __esm({
|
|
|
7985
8070
|
try {
|
|
7986
8071
|
await this.postBatch(batch, `event_batch:${batch.length}`);
|
|
7987
8072
|
} catch (err) {
|
|
7988
|
-
console.
|
|
8073
|
+
if (this.debug) console.log("[Paywallo:NORMAL] batch post failed \u2014 relying on OfflineQueue", { batchSize: batch.length, error: err instanceof Error ? err.message : String(err) });
|
|
7989
8074
|
}
|
|
7990
8075
|
}
|
|
7991
8076
|
async postBatch(events, label, priority = "normal") {
|
|
@@ -8000,7 +8085,7 @@ var init_EventBatcher = __esm({
|
|
|
8000
8085
|
const parsed = v2EnvelopeSchema.safeParse(envelope);
|
|
8001
8086
|
if (!parsed.success) {
|
|
8002
8087
|
if (this.debug) console.log("[Paywallo EVENTS] V2 envelope schema validation failed:", parsed.error.issues);
|
|
8003
|
-
console.
|
|
8088
|
+
if (this.debug) console.log("[Paywallo:CRITICAL] V2 envelope schema validation failed", { issues: parsed.error.issues, eventCount: events.length, firstEventName: events[0]?.eventName, context: providerContext });
|
|
8004
8089
|
throw parsed.error;
|
|
8005
8090
|
}
|
|
8006
8091
|
await this.post(V2_BATCH_ENDPOINT, parsed.data, label, priority);
|
|
@@ -8258,6 +8343,7 @@ function buildPiiPayload(pii) {
|
|
|
8258
8343
|
if (dob) result.dateOfBirth = dob;
|
|
8259
8344
|
const g = normalizeGender(pii.gender);
|
|
8260
8345
|
if (g) result.gender = g;
|
|
8346
|
+
if (pii.zipCode) result.zipCode = pii.zipCode.trim();
|
|
8261
8347
|
return result;
|
|
8262
8348
|
}
|
|
8263
8349
|
function normalizeGender(raw) {
|
|
@@ -8267,12 +8353,13 @@ function normalizeGender(raw) {
|
|
|
8267
8353
|
if (lower === "f" || lower === "female") return "f";
|
|
8268
8354
|
return void 0;
|
|
8269
8355
|
}
|
|
8270
|
-
var
|
|
8356
|
+
var import_react_native28, DATE_OF_BIRTH_RE, ApiClient;
|
|
8271
8357
|
var init_ApiClient = __esm({
|
|
8272
8358
|
"src/core/ApiClient.ts"() {
|
|
8273
8359
|
"use strict";
|
|
8274
|
-
|
|
8360
|
+
import_react_native28 = require("react-native");
|
|
8275
8361
|
init_apiPurchaseMethods();
|
|
8362
|
+
init_userAgent();
|
|
8276
8363
|
init_ApiCache();
|
|
8277
8364
|
init_ApiClientFlags();
|
|
8278
8365
|
init_ApiClientQueue();
|
|
@@ -8372,10 +8459,13 @@ var init_ApiClient = __esm({
|
|
|
8372
8459
|
* should carry. Keep this tiny — it runs once per ApiClient instance.
|
|
8373
8460
|
*/
|
|
8374
8461
|
buildSdkHeaders() {
|
|
8462
|
+
const ua = buildUserAgent(SDK_VERSION);
|
|
8375
8463
|
return {
|
|
8376
8464
|
"x-sdk-version": SDK_VERSION,
|
|
8377
|
-
"x-sdk-platform":
|
|
8378
|
-
"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
|
|
8379
8469
|
};
|
|
8380
8470
|
}
|
|
8381
8471
|
async clearQueue() {
|
|
@@ -8404,7 +8494,7 @@ var init_ApiClient = __esm({
|
|
|
8404
8494
|
message,
|
|
8405
8495
|
context,
|
|
8406
8496
|
sdkVersion: SDK_VERSION,
|
|
8407
|
-
platform:
|
|
8497
|
+
platform: import_react_native28.Platform.OS
|
|
8408
8498
|
}, true);
|
|
8409
8499
|
} catch (err) {
|
|
8410
8500
|
if (this.debug) console.log("[Paywallo:ApiClient] reportError failed", err);
|
|
@@ -8422,7 +8512,7 @@ var init_ApiClient = __esm({
|
|
|
8422
8512
|
async identify(distinctId, properties, email, deviceId, pii) {
|
|
8423
8513
|
const rawTraits = {
|
|
8424
8514
|
email: email || void 0,
|
|
8425
|
-
platform:
|
|
8515
|
+
platform: import_react_native28.Platform.OS,
|
|
8426
8516
|
name: properties?.name,
|
|
8427
8517
|
country: properties?.country,
|
|
8428
8518
|
locale: properties?.locale,
|
|
@@ -8618,7 +8708,6 @@ function setupNotifications(apiClient, config, environment, eventPipeline) {
|
|
|
8618
8708
|
notificationsManager.setupHandlers({ eventBatcher: eventPipeline });
|
|
8619
8709
|
notificationsManager.initialize({
|
|
8620
8710
|
appKey: config.appKey,
|
|
8621
|
-
apiBaseUrl: DEFAULT_API_URL,
|
|
8622
8711
|
debug: config.debug,
|
|
8623
8712
|
environment: environment === "Sandbox" ? "sandbox" : "production"
|
|
8624
8713
|
}).catch((err) => {
|
|
@@ -8660,7 +8749,6 @@ var init_PaywalloInitHelpers = __esm({
|
|
|
8660
8749
|
init_identity();
|
|
8661
8750
|
init_notifications();
|
|
8662
8751
|
init_NativePushBridge();
|
|
8663
|
-
init_constants();
|
|
8664
8752
|
init_SecureStorage();
|
|
8665
8753
|
}
|
|
8666
8754
|
});
|
|
@@ -8750,7 +8838,7 @@ function reportInitFailure(state, config, error, reason) {
|
|
|
8750
8838
|
error: error instanceof Error ? error.message : String(error)
|
|
8751
8839
|
});
|
|
8752
8840
|
} catch (err) {
|
|
8753
|
-
console.
|
|
8841
|
+
if (config.debug) console.log("[Paywallo] reportInitFailure error", err);
|
|
8754
8842
|
}
|
|
8755
8843
|
}
|
|
8756
8844
|
function reportInitSuccess(state, config, attempts) {
|
|
@@ -8759,7 +8847,7 @@ function reportInitSuccess(state, config, attempts) {
|
|
|
8759
8847
|
void state.apiClient.reportError("INIT_RECOVERED", `Succeeded after ${attempts} retries`, { attempts });
|
|
8760
8848
|
}
|
|
8761
8849
|
} catch (err) {
|
|
8762
|
-
console.
|
|
8850
|
+
if (config.debug) console.log("[Paywallo] reportInitSuccess error", err);
|
|
8763
8851
|
}
|
|
8764
8852
|
}
|
|
8765
8853
|
async function resolveSessionFlags(state, keys, apiClient, distinctId) {
|
|
@@ -8835,9 +8923,14 @@ async function doInit(state, config) {
|
|
|
8835
8923
|
} catch (err) {
|
|
8836
8924
|
if (config.debug) console.log("[Paywallo ATTR] start error", err);
|
|
8837
8925
|
}
|
|
8838
|
-
|
|
8839
|
-
|
|
8840
|
-
|
|
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
|
+
]);
|
|
8841
8934
|
apiClient.setEventContextProvider(() => {
|
|
8842
8935
|
const attr = attributionTracker.get();
|
|
8843
8936
|
const attrEntries = attr ? [
|
|
@@ -8874,10 +8967,10 @@ async function doInit(state, config) {
|
|
|
8874
8967
|
let screenHeight;
|
|
8875
8968
|
let screenDensity;
|
|
8876
8969
|
try {
|
|
8877
|
-
const screen =
|
|
8970
|
+
const screen = import_react_native29.Dimensions.get("screen");
|
|
8878
8971
|
screenWidth = Math.round(screen.width) || void 0;
|
|
8879
8972
|
screenHeight = Math.round(screen.height) || void 0;
|
|
8880
|
-
screenDensity =
|
|
8973
|
+
screenDensity = import_react_native29.PixelRatio.get() || void 0;
|
|
8881
8974
|
} catch {
|
|
8882
8975
|
}
|
|
8883
8976
|
return {
|
|
@@ -8913,12 +9006,15 @@ async function doInit(state, config) {
|
|
|
8913
9006
|
setupNotifications(apiClient, config, environment, eventPipeline);
|
|
8914
9007
|
if (config.autoStartSession !== false) {
|
|
8915
9008
|
sessionManager.startSession().catch((err) => {
|
|
8916
|
-
console.
|
|
9009
|
+
if (config.debug) console.log("[Paywallo INIT] autoStart session error", err);
|
|
8917
9010
|
});
|
|
8918
9011
|
}
|
|
8919
9012
|
new InstallTracker(config.debug, {
|
|
8920
9013
|
distinctIdProvider: () => identityManager.getDistinctId()
|
|
8921
|
-
}).trackIfNeeded(apiClient, config.requestATT === true).
|
|
9014
|
+
}).trackIfNeeded(apiClient, config.requestATT === true).then(() => {
|
|
9015
|
+
if (config.debug) console.log("[Paywallo INSTALL] $app_installed sent");
|
|
9016
|
+
}).catch(() => {
|
|
9017
|
+
if (config.debug) console.log("[Paywallo INSTALL] $app_installed failed \u2014 will retry on next launch");
|
|
8922
9018
|
});
|
|
8923
9019
|
if (config.sessionFlags && config.sessionFlags.length > 0) {
|
|
8924
9020
|
await resolveSessionFlags(state, config.sessionFlags, apiClient, distinctId);
|
|
@@ -8944,11 +9040,11 @@ async function doInit(state, config) {
|
|
|
8944
9040
|
setupAutoPreload(state, apiClient, config, distinctId);
|
|
8945
9041
|
startBatchPreload(apiClient, config.debug);
|
|
8946
9042
|
}
|
|
8947
|
-
var
|
|
9043
|
+
var import_react_native29;
|
|
8948
9044
|
var init_PaywalloInitializer = __esm({
|
|
8949
9045
|
"src/core/PaywalloInitializer.ts"() {
|
|
8950
9046
|
"use strict";
|
|
8951
|
-
|
|
9047
|
+
import_react_native29 = require("react-native");
|
|
8952
9048
|
init_identity();
|
|
8953
9049
|
init_AdvertisingIdManager();
|
|
8954
9050
|
init_DeepLinkAttributionCapture();
|
|
@@ -9155,6 +9251,7 @@ var init_PaywalloClient = __esm({
|
|
|
9155
9251
|
}
|
|
9156
9252
|
if (this.state.config?.debug) console.log("[Paywallo IDENTIFY]", options ? { hasEmail: "email" in options && !!options.email, hasProperties: "properties" in options } : void 0);
|
|
9157
9253
|
await identityManager.identify(options);
|
|
9254
|
+
if (this.state.config?.debug) console.log("[Paywallo IDENTIFY] done");
|
|
9158
9255
|
}
|
|
9159
9256
|
async track(eventName, options) {
|
|
9160
9257
|
return trackEvent(this.getApiClientOrThrow(), this.state, eventName, options);
|
|
@@ -9389,7 +9486,7 @@ __export(OfferingService_exports, {
|
|
|
9389
9486
|
offeringService: () => offeringService
|
|
9390
9487
|
});
|
|
9391
9488
|
function resolveProductId(raw) {
|
|
9392
|
-
const isIos =
|
|
9489
|
+
const isIos = import_react_native30.Platform.OS === "ios";
|
|
9393
9490
|
const productId = isIos ? raw.apple_product_id : raw.google_product_id;
|
|
9394
9491
|
return productId ?? "";
|
|
9395
9492
|
}
|
|
@@ -9408,7 +9505,7 @@ function mapProduct2(raw) {
|
|
|
9408
9505
|
};
|
|
9409
9506
|
}
|
|
9410
9507
|
function pickPlatformProduct(products) {
|
|
9411
|
-
const isIos =
|
|
9508
|
+
const isIos = import_react_native30.Platform.OS === "ios";
|
|
9412
9509
|
const match = products.find((p) => isIos ? p.apple_product_id : p.google_product_id);
|
|
9413
9510
|
return match ?? products[0] ?? null;
|
|
9414
9511
|
}
|
|
@@ -9424,11 +9521,11 @@ function mapOffering(raw) {
|
|
|
9424
9521
|
product: mapProduct2(rawProduct)
|
|
9425
9522
|
};
|
|
9426
9523
|
}
|
|
9427
|
-
var
|
|
9524
|
+
var import_react_native30, OFFERINGS_CACHE_KEY, DEFAULT_TTL3, OfferingService, offeringService;
|
|
9428
9525
|
var init_OfferingService = __esm({
|
|
9429
9526
|
"src/domains/offering/OfferingService.ts"() {
|
|
9430
9527
|
"use strict";
|
|
9431
|
-
|
|
9528
|
+
import_react_native30 = require("react-native");
|
|
9432
9529
|
init_SecureStorage();
|
|
9433
9530
|
OFFERINGS_CACHE_KEY = "@paywallo:offerings_cache";
|
|
9434
9531
|
DEFAULT_TTL3 = 5 * 60 * 1e3;
|
|
@@ -9715,18 +9812,14 @@ var import_react15 = require("react");
|
|
|
9715
9812
|
init_onboarding();
|
|
9716
9813
|
function useOnboarding() {
|
|
9717
9814
|
const step = (0, import_react15.useCallback)(
|
|
9718
|
-
(stepName, order) => onboardingManager.step(stepName, order),
|
|
9815
|
+
(stepName, order, options) => onboardingManager.step(stepName, order, options),
|
|
9719
9816
|
[]
|
|
9720
9817
|
);
|
|
9721
9818
|
const complete = (0, import_react15.useCallback)(
|
|
9722
|
-
() => onboardingManager.complete(),
|
|
9723
|
-
[]
|
|
9724
|
-
);
|
|
9725
|
-
const drop = (0, import_react15.useCallback)(
|
|
9726
|
-
(stepName) => onboardingManager.drop(stepName),
|
|
9819
|
+
(options) => onboardingManager.complete(options),
|
|
9727
9820
|
[]
|
|
9728
9821
|
);
|
|
9729
|
-
return { step, complete
|
|
9822
|
+
return { step, complete };
|
|
9730
9823
|
}
|
|
9731
9824
|
|
|
9732
9825
|
// src/hooks/usePaywallo.ts
|
|
@@ -10094,7 +10187,7 @@ function useSubscription() {
|
|
|
10094
10187
|
|
|
10095
10188
|
// src/PaywalloProvider.tsx
|
|
10096
10189
|
var import_react28 = require("react");
|
|
10097
|
-
var
|
|
10190
|
+
var import_react_native31 = require("react-native");
|
|
10098
10191
|
init_PaywalloClient();
|
|
10099
10192
|
init_NativeStorage();
|
|
10100
10193
|
init_SecureStorage();
|
|
@@ -10986,8 +11079,8 @@ function PaywalloProvider({ children, config }) {
|
|
|
10986
11079
|
});
|
|
10987
11080
|
}, []);
|
|
10988
11081
|
const { showingPreloadedWebView, presentPreloadedWebView, resolvePreloadedPaywall, handlePreloadedWebViewReady: baseHandlePreloadedWebViewReady, handlePreloadedClose: baseHandlePreloadedClose, setShowingPreloadedWebView, presentedAtRef } = usePaywallPresenter(preloadedWebView, setPreloadedWebView);
|
|
10989
|
-
const SCREEN_HEIGHT = (0, import_react28.useMemo)(() =>
|
|
10990
|
-
const slideAnim = (0, import_react28.useRef)(new
|
|
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;
|
|
10991
11084
|
const handlePreloadedWebViewReady = (0, import_react28.useCallback)(() => {
|
|
10992
11085
|
if (PaywalloClient.getConfig()?.debug) {
|
|
10993
11086
|
console.log(`[Paywallo WEBVIEW] loaded \u2014 placement: ${preloadedWebView?.placement}`);
|
|
@@ -10996,7 +11089,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
10996
11089
|
}, [preloadedWebView?.placement, baseHandlePreloadedWebViewReady]);
|
|
10997
11090
|
const handlePreloadedClose = (0, import_react28.useCallback)(() => {
|
|
10998
11091
|
const placement = preloadedWebView?.placement;
|
|
10999
|
-
|
|
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(() => {
|
|
11000
11093
|
baseHandlePreloadedClose();
|
|
11001
11094
|
if (placement) triggerRepreload(placement);
|
|
11002
11095
|
});
|
|
@@ -11040,6 +11133,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
11040
11133
|
void pushAttributionToSuperwall(configRef.current.debug);
|
|
11041
11134
|
setDistinctId(PaywalloClient.getDistinctId());
|
|
11042
11135
|
setIsInitialized(true);
|
|
11136
|
+
if (configRef.current.debug) console.log("[Paywallo] SDK ready", PaywalloClient.getDistinctId()?.slice(0, 8));
|
|
11043
11137
|
if (!autoPreloadTriggeredRef.current) {
|
|
11044
11138
|
autoPreloadTriggeredRef.current = true;
|
|
11045
11139
|
const placement = await PaywalloClient.waitForAutoPreloadedPlacement();
|
|
@@ -11280,7 +11374,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
11280
11374
|
(0, import_react28.useLayoutEffect)(() => {
|
|
11281
11375
|
if (showingPreloadedWebView) {
|
|
11282
11376
|
slideAnim.setValue(SCREEN_HEIGHT);
|
|
11283
|
-
|
|
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();
|
|
11284
11378
|
}
|
|
11285
11379
|
}, [showingPreloadedWebView, slideAnim, SCREEN_HEIGHT]);
|
|
11286
11380
|
const preloadStyle = [
|
|
@@ -11290,7 +11384,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
11290
11384
|
];
|
|
11291
11385
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(PaywalloContext.Provider, { value: contextValue, children: [
|
|
11292
11386
|
children,
|
|
11293
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaywallErrorBoundary, { children: !!preloadedWebView?.craftData && /* @__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)(
|
|
11294
11388
|
PaywallWebView,
|
|
11295
11389
|
{
|
|
11296
11390
|
paywallId: preloadedWebView.paywallId,
|
|
@@ -11322,7 +11416,7 @@ function PaywalloProvider({ children, config }) {
|
|
|
11322
11416
|
isInitialized && (config.preloadPaywalls?.length ?? 0) > 0 && PaywalloClient.getWebUrl() !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PaywallWebViewPrewarmer, { webUrl: PaywalloClient.getWebUrl() })
|
|
11323
11417
|
] });
|
|
11324
11418
|
}
|
|
11325
|
-
var styles5 =
|
|
11419
|
+
var styles5 = import_react_native31.StyleSheet.create({
|
|
11326
11420
|
preloadOverlay: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, backgroundColor: "#ffffff" },
|
|
11327
11421
|
hidden: { zIndex: -1, opacity: 0, width: 1, height: 1, overflow: "hidden" },
|
|
11328
11422
|
visible: { zIndex: 9999, opacity: 1 }
|